成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

React性能優化之useMemo、useCallback

開發 前端
記憶化用于提高React應用程序的性能,記憶化用于跳過組件的不必要重新渲染。useMemo和useCallback?鉤子分別用于記憶化返回值和函數聲明。雖然useMemo和useCallback?的行為類似,但兩者之間存在關鍵差異。useMemo?返回調用函數的結果;useCallback返回函數本身。

前言

在React應用程序中進行性能優化至關重要,因為它直接影響用戶體驗,隨后影響轉化率和用戶留存率。一個經過優化的React應用加載更快,響應迅速,消耗更少的資源,從而為用戶提供更順暢的互動體驗。優化React應用程序的性能對于保留和吸引用戶、降低跳出率以及最終實現所期望的業務結果至關重要。

記憶化(Memoization)是改善React應用程序性能的一種方式。記憶化涉及緩存值和函數以實現更快的渲染。

在本文中,我們將了解什么是記憶化以及如何使用useMemo和useCallback鉤子來實現記憶化。

理解React中的記憶化

記憶化是存儲計算結果的過程,以便在不重新計算的情況下檢索它。記憶化用于跳過組件的不必要重新渲染。

在React中,可以通過使用useMemo和useCallback鉤子來實現記憶化。這些鉤子允許你通過緩存函數調用和函數本身來跳過重新渲染。

使用useMemo入門

useMemo鉤子用于緩存函數調用。useMemo鉤子接受兩個參數:

  • 函數
  • 依賴項數組
const doubledNumber = useMemo(() => {
  return someExpensiveCalculation(number);
}, [number]);

useMemo鉤子在第一次渲染時返回調用函數的結果。在后續重新渲染中,useMemo鉤子將提供你的函數調用的緩存值,除非至少一個依賴項發生更改。

在JavaScript中,函數在代碼再次運行時會被重新創建。這意味著盡管函數的代碼相同,但每次應用程序重新渲染時,你的函數并不相同。這是因為JavaScript對象和函數是引用對象。

useMemo鉤子旨在通過緩存調用函數的結果來消除函數的重新創建。在后續重新渲染中,useMemo鉤子會返回緩存的值,跳過函數的重新創建。

讓我們通過一個實際示例來了解如何在React中使用useMemo。

在這個示例中,我們正在對幾千篇博客文章進行排序,并將每篇博客文章顯示在屏幕上。在每次重新渲染時對博客文章進行排序可能會減慢我們的應用程序。

使用useMemo鉤子來跳過博客文章的排序,如果文章列表沒有更改。

function PostList({ posts }) {
  const sortedPosts = useMemo(() => {
    return [...posts].sort((a, b) => a.date - b.date);
  }, [posts]);

  return (
    <div>
      <h2>已排序的文章</h2>
      <ul>
        {sortedPosts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

useMemo鉤子用于緩存sortedPosts。只有在posts的值更改時,sortedPosts才會重新計算。

通過這種方式,排序操作僅在文章數組更改時發生,從而跳過重新渲染并提高性能。

充分利用useCallback的能力

useCallback用于緩存函數聲明。它同樣接受兩個參數:

  • 函數
  • 依賴項數組

與useMemo不同,useCallback不會調用你的函數。useCallback只是將函數返回給你。你可以自行決定何時以及是否調用函數。

useCallback鉤子的工作方式與useMemo鉤子類似。useCallback通過返回函數的緩存版本來消除函數的重新創建。只有在依賴項中的至少一個值發生更改時,才會重新創建你的函數。

讓我們看一個使用useCallback來優化React應用程序的示例。

在React組件中,當單擊按鈕時,你有一個對產品數組進行排序的函數。在每次重新渲染時,這個排序函數都會被重新創建。

使用useCallback鉤子來緩存sortPosts函數聲明,以及posts狀態作為一個依賴項。

import React, { useState, useCallback } from 'react';

function PostList() {
  const [posts, setPosts] = useState([
    { id: 1, title: '文章1', date: new Date('2023-10-15T00:00:00.000Z') },
    { id: 2, title

: '文章2', date: new Date('2023-10-10T00:00:00.000Z') },
    { id: 3, title: '文章3', date: new Date('2023-10-20T00:00:00.000Z') },
  ]);

  const sortPosts = useCallback(() => {
    const sortedPosts = [...posts].sort((a, b) => a.date - b.date);
    setPosts(sortedPosts);
  }, [posts]);

  return (
    <div>
      <button onClick={sortPosts}>排序文章</button>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        )}
      </ul>
    </div>
  );
}

export default PostList;

現在,只有當posts狀態更改時,sortPosts函數才會被重新創建,從而提高我們的React應用程序性能。

通過結合使用useCallback和useMemo來優化性能

useCallback和useMemo鉤子可以一起使用,以獲得顯著的性能提升。

React組件重新渲染依賴以下兩個條件:

  • 狀態發生變化
  • 屬性發生變化

通過useCallback鉤子,你可以緩存屬性(如果是一個函數),然后將其傳遞給包裝在useMemo中的子組件。

接下來看一個將useCallback與useMemo結合使用的示例。

假設你正在為網站開發產品列表頁面。用戶可以根據價格、品牌和類別等各種標準對產品進行篩選和排序。

如果不使用useCallback和useMemo鉤子,你的ProductList組件將如下所示:

javascriptCopy code
import React, { useState } from 'react';

function ProductList({ products }) {
  const [filter, setFilter] = useState('');
  const [sortBy, setSortBy] = useState('price');

  // 根據用戶輸入篩選產品
  const filteredProducts = products.filter(product =>
    product.title.toLowerCase().includes(filter.toLowerCase())
  );

  // 對篩選后的產品進行排序
  const sortedProducts = [...filteredProducts].sort((a, b) => {
    if (sortBy === 'price') {
      return a.price - b.price;
    } else if sortBy === 'rating') {
      return b.rating - a.rating;
    }
    // 在這里處理其他排序條件
  });

  // 處理篩選更改
  const handleFilterChange = (event) => {
    setFilter(event.target.value);
  };

  // 處理排序更改
  const handleSortChange = (event) => {
    setSortBy(event.target.value);
  };

  return (
    <div>
      <input
        type="text"
        placeholder="篩選產品"
        value={filter}
        onChange={handleFilterChange}
      />
      <select value={sortBy} onChange={handleSortChange}>
        <option value="price">價格</option>
        <option value="rating">評分</option>
        {/* 根據需要添加更多排序選項 */}
      </select>
      <ul>
        {sortedProducts.map(product => (
          <li key={product.id}>{product.title}</li>
        )}
      </ul>
    </div>
  );
}

export default ProductList;

雖然ProductList組件沒有問題,但它可能導致不必要的重新渲染和性能瓶頸。

如果ProductList處理大量產品,不必要的重新渲染會減慢你的電子商務站點。

使用useMemo和useCallback鉤子來減輕不必要的重新渲染并加速你的網站。

javascriptCopy code
import React, { useState, useMemo, useCallback } from 'react';

function ProductList({ products }) {
  const [filter, setFilter] = useState('');
  const [sortBy, setSortBy] = useState('price');

  // 根據用戶輸入篩選產品
  const filteredProducts = useMemo(() => {
    return products.filter(product => product.title.toLowerCase().includes(filter.toLowerCase()));
  }, [products, filter]);

  // 對篩選后的產品進行排序
  const sortedProducts = useMemo(() => {
    return [...filteredProducts].sort((a, b) => {
      if (sortBy === 'price') {
        return a.price - b.price;
      } else if sortBy === 'rating') {
        return b.rating - a.rating;
      }
      // 在這里處理其他排序條件
    });
  }, [filteredProducts, sortBy]);

  // 記憶化回調來處理篩選更改
  const handleFilterChange = useCallback((event) => {
    setFilter(event.target.value);
  }, []);

  // 記憶化回調來處理排序更改
  const handleSortChange = useCallback((event) => {
    setSortBy(event.target.value);
  }, []);

  return (
    <div>
      <input
        type="text"
        placeholder="篩選產品"
        value={filter}
        onChange={handleFilterChange}
      />
      <select value={sortBy} onChange={handleSortChange}>
        <option value="price">價格</option>
        <option value="rating">評分</option>
        {/* 根據需要添加更多排序選項 */}
      </select>
      <ul>
        {sortedProducts.map(product => (
          <li key={product.id}>{product.title}</li>
        )}
      </ul>
    </div>
  );
}

export default ProductList;

在這個經過優化的ProductList組件版本中,useMemo用于優化篩選和排序操作,而useCallback用于記憶化篩選和排序更改的事件處理程序函數。ProductList組件僅在products的值發生變化時重新渲染。

注意事項

盡管useMemo和useCallback是性能優化鉤子,但開發人員往往會過度使用這些鉤子。有些情況下,使用useMemo和useCallback并不對你的應用程序產生大的收益。由于現代計算機的快速性質,大多數操作都是廉價的。在操作廉價的情況下,你不需要useMemo和useCallback鉤子。例如,你有一個要排序的包含100個帖子的數組。使用useMemo或useCallback鉤子不會帶來任何性能提升,因為排序操作只需要幾毫秒。

總結

記憶化用于提高React應用程序的性能,記憶化用于跳過組件的不必要重新渲染。useMemo和useCallback鉤子分別用于記憶化返回值和函數聲明。雖然useMemo和useCallback的行為類似,但兩者之間存在關鍵差異。useMemo返回調用函數的結果;useCallback返回函數本身。

useMemo和useCallback鉤子有助于優化性能,但使用它們也可能帶來一些潛在問題,如過度優化和增加代碼復雜性。

責任編輯:武曉燕 來源: 前端大濕兄
相關推薦

2025-04-03 07:37:55

2021-08-27 14:26:06

開發技能React

2019-02-25 07:07:38

技巧React 優化

2023-12-20 14:48:26

2022-08-03 09:11:31

React性能優化

2016-12-19 10:00:00

React性能優化

2023-11-29 09:00:55

ReactuseMemo

2023-02-14 06:40:33

React HookReact

2021-07-29 14:20:34

網絡優化移動互聯網數據存儲

2020-06-22 07:30:00

React開發工具

2022-02-16 14:10:51

服務器性能優化Linux

2021-11-29 11:13:45

服務器網絡性能

2019-03-14 15:38:19

ReactJavascript前端

2009-06-30 11:23:02

性能優化

2018-01-09 16:56:32

數據庫OracleSQL優化

2019-12-13 10:25:08

Android性能優化啟動優化

2013-02-20 14:32:37

Android開發性能

2011-07-11 15:26:49

性能優化算法

2023-07-19 12:24:48

C++constexpr?語句

2025-01-20 09:09:59

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一区二区在线播放 | 亚洲精选一区二区 | 国产高清在线精品 | 黑人巨大精品欧美一区二区免费 | 91国产精品在线 | 国产成人自拍av | 欧美成视频 | 性做久久久久久免费观看欧美 | 中文一区二区 | 干干天天| 日日综合 | a级片在线观看 | 激情a | 久久精品91久久久久久再现 | 免费国产精品久久久久久 | 国产精品一区二区三区在线 | 91视频入口 | 久色视频在线观看 | 亚洲一区中文字幕 | 搞av.com| 国产精品1区2区 | 国产剧情久久 | 国产九九九九 | 国产一级片网站 | 久久久久久久综合色一本 | 精品久久一区 | 国产免费观看一区 | 国产在线精品一区二区三区 | 成人午夜视频在线观看 | 亚洲女人天堂成人av在线 | 久久y| 日本中文字幕在线视频 | 成人在线国产 | 蜜桃特黄a∨片免费观看 | 99热这里都是精品 | a级毛片基地 | 国产三区在线观看视频 | 国产在线视频网 | 午夜精品一区二区三区免费视频 | www狠狠爱com | 国产一区不卡在线观看 |