」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 避免 React 中不必要的重新渲染

避免 React 中不必要的重新渲染

發佈於2024-11-08
瀏覽:220

Avoiding Unnecessary Re-renders in React

建立高效能 React 應用程式的關鍵之一是避免不必要的重新渲染。 React 的渲染引擎非常高效,但防止在不需要的地方重新渲染仍然至關重要。在這篇文章中,我們將介紹常見錯誤以及如何避免這些錯誤。


1. 使用 React.memo 記憶組件

當元件的 props 沒有改變時,Memoization 可以幫助你跳過重新渲染。然而,如果不實作自訂比較函數,很容易誤用 React.memo。

錯誤用法:

const MemoizedComponent = React.memo(MyComponent);

這僅檢查 props 引用是否已更改,這可能並不總是足夠的。

正確用法:

const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
  return prevProps.itemId === nextProps.itemId;
});

這裡,我們使用自訂比較函數,只有在 itemId 屬性變更時才會觸發重新渲染。


2. 避免過度使用內聯函數

在 JSX 中使用內聯函數可能會導致不必要的重新渲染,因為 React 在每次渲染時都會將新函數視為新的 prop。

錯誤用法:

function ButtonComponent() {
  return ;
}

這會導致在每次渲染時重新建立handleClick,從而導致不必要的重新渲染。

正確用法:

import { useCallback } from 'react';

function ButtonComponent() {
  const handleClick = useCallback(() => {
    // Handle click logic
  }, []);

  return ;
}

透過使用 useCallback,我們記住了 handleClick 函數,從而防止在每次渲染時進行不必要的重新創建。


3. 利用 PureComponent

使用類別元件時,使用 React.PureComponent 可確保元件僅在其 props 或狀態變更時重新渲染。如果您使用 React.Component,可能會導致不必要的重新渲染。

錯誤用法:

class CardComponent extends React.Component {
  // Component logic
}

正確用法:

class CardComponent extends React.PureComponent {
  // Component logic
}

透過擴展 React.PureComponent,React 將淺層比較 props 和 state,避免不必要的重新渲染。


4. 優化功能組件中的useSelector

當使用react-redux中的useSelector時,僅選擇狀態的必要部分非常重要。

錯誤用法:

import { useSelector } from 'react-redux';

const DataComponent = () => {
  const globalState = useSelector((state) => state);
  // Render logic
};

每當狀態的任何部分發生變化時,這將導致元件重新渲染。

正確用法:

import { useSelector } from 'react-redux';

const DataComponent = () => {
  const selectedData = useSelector((state) => state.specificSlice);
  // Render logic based on specific slice
};

透過僅選擇狀態的必要部分,可以最大限度地減少重新渲染。


5. 在類別元件中實作shouldComponentUpdate

對於不擴展 PureComponent 的類別元件,手動實作 shouldComponentUpdate 可以更精細地控制元件何時重新渲染。

錯誤用法:

class ListItem extends React.Component {
  // Component logic
}

每次父元件渲染時都會重新渲染,即使 props 和 state 沒有改變。

正確用法:

class ListItem extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    return this.props.itemId !== nextProps.itemId || this.state.value !== nextState.value;
  }

  // Component logic
}

透過自訂shouldComponentUpdate,我們確保元件僅在itemId屬性或值狀態變更時重新渲染。


結論

透過採用這些技術,您可以大幅減少 React 應用程式中不必要的重新渲染,從而獲得更好的效能。使用 React.memo 實現記憶化、利用 PureComponent 以及微調 shouldComponentUpdate 是優化 React 元件的關鍵策略。

了解何時以及如何優化渲染可以透過提供更快、響應更靈敏的應用程式來大大增強用戶體驗。


參考:

  1. 極客們的極客們。 (2023)。 React 中的記憶化是什麼?
  2. 同步融合。 (2024)。 React 中的記憶化
  3. Hygraph。 (2024)。什麼是 React Memo 以及如何使用它?
  4. Refine.dev。 (2024)。帶有範例的 React 備忘錄指南

如果您發現本指南有用,請考慮與其他人分享! ?


本部落格提供了更新且全面的概述,介紹如何避免 React 應用程式中不必要的重新渲染,同時結合最佳實踐並更改變數名稱,以確保現代 Web 開發實踐中的清晰度和相關性。

引用:
[1] https://www.geeksforgeeks.org/what-is-memoization-in-react/
[2] https://stackoverflow.com/questions/74013864/why-arent-all-react-components-wrapped-with-react-memo-by-default
[3] https://www.syncfusion.com/blogs/post/what-is-memoization-in-react
[4] https://hygraph.com/blog/react-memo
[5] https://refine.dev/blog/react-memo-guide/
[6] https://dmitripavlutin.com/use-react-memo-wisely/
[7] https://www.topcoder.com/thrive/articles/memoization-in-react-js
[8] https://react.dev/reference/react/memo

版本聲明 本文轉載於:https://dev.to/vyan/avoiding-unnecessary-re-renders-in-react-172k?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 使用 Unity 建立擴增實境應用程式
    使用 Unity 建立擴增實境應用程式
    介紹 隨著智慧型手機的興起和 3D 圖形的進步,擴增實境 (AR) 近年來已成為一項流行技術。它允許用戶與現實世界中的數位元素交互,創造身臨其境的、引人入勝的體驗。 Unity 是創建 AR 應用程式最強大的工具之一,它是一種廣泛應用於遊戲產業的遊戲引擎。在本文中,我們將探討使用 ...
    程式設計 發佈於2024-11-08
  • JavaScript 如何提供原生 JSON 解析和序列化?
    JavaScript 如何提供原生 JSON 解析和序列化?
    瀏覽器原生JSON 解析與序列化瀏覽器原生JSON 解析與序列化window.JSON 物件在現代瀏覽器中提供原生JSON 支持,包括Internet Explorer 8 、 Firefox 3.1、Safari 4 和Chrome 3。該物件公開兩個方法:JSON.parse(str)解析 JS...
    程式設計 發佈於2024-11-08
  • 使用 STMMCU 實現靜電除塵器控制器的 SPWM ase/ase 逆變器
    使用 STMMCU 實現靜電除塵器控制器的 SPWM ase/ase 逆變器
    前段時間提到中頻電除塵器控制器,我仔細分析了單相和三相SPWM驅動時間,完成了STM32F103處理器上SPWM程式碼的編寫,並用示波器測試了訊號和波形,邏輯分析儀。 STM32F103的TIMER1和TIMER2支援互補的PWM輸出,我選擇TIMER1的CH1、CH2、CH3用於A、B、C三相驅...
    程式設計 發佈於2024-11-08
  • 我們必須了解開源工具,讓您比開發人員更優秀
    我們必須了解開源工具,讓您比開發人員更優秀
    The software development landscape is evolving faster than ever. To stay ahead of the curve, you must arm yourself with tools and technologies built f...
    程式設計 發佈於2024-11-08
  • # 終極指南:QA 自動化工程師的調試技術
    # 終極指南:QA 自動化工程師的調試技術
    ?️ 面对让您摸不着头脑的测试失败? 调试可能感觉像是一场徒劳的追逐,但通过正确的技术,您可以加快工作流程并更快地发现问题。在这篇文章中,我将分享每个 QA 自动化工程师在他们的工具包中应该拥有的实用调试方法,以提供更可靠的自动化脚本。 ? 为什么调试在自动化测试中很重要 调试对于以...
    程式設計 發佈於2024-11-08
  • 如何使用 Java Lookahead 和 Lookbehind 拆分字串並保留分隔符號?
    如何使用 Java Lookahead 和 Lookbehind 拆分字串並保留分隔符號?
    使用保留的分隔符號分割字串處理由一組唯一分隔符號分隔的多行字串時,分割字串可能會很困難同時還保留分隔符號本身。標準 String.split 方法僅根據指定的分隔符號分隔字串,並丟棄分隔符號。 使用 Lookahead 和 LookbehindJava 開發工具包(JDK)提供了使用lookahea...
    程式設計 發佈於2024-11-08
  • 為什麼 np.vectorize() 比 df.apply() 對於 Pandas 列創建更快?
    為什麼 np.vectorize() 比 df.apply() 對於 Pandas 列創建更快?
    Pandas apply 與 np.vectorize 的表現比較據觀察,np.vectorize() 可以明顯快於 df。基於 Pandas DataFrame 中的現有欄位建立新欄位時使用 apply() 。觀察到的性能差異源自於這兩種方法所採用的底層機制。 df.apply() 與 Pytho...
    程式設計 發佈於2024-11-08
  • 如何修復由於 MySQL 嚴格模式導致 Laravel Eloquent 中的「SELECT 清單的表達式 #1 不在 GROUP BY 子句中」錯誤?
    如何修復由於 MySQL 嚴格模式導致 Laravel Eloquent 中的「SELECT 清單的表達式 #1 不在 GROUP BY 子句中」錯誤?
    Laravel Eloquent 中與sql_mode=only_full_group_by 不相容遇到錯誤「SELECT 清單的表達式#1 不在GROUP BY 子句中.. ." 當執行帶有分組的Eloquent 查詢時,表示與MySQL不相容於sql_mode=only_full_gr...
    程式設計 發佈於2024-11-08
  • TypeScript:因為 JavaScript 需要更多的紀律
    TypeScript:因為 JavaScript 需要更多的紀律
    JavaScript 很棒,但讓我們面對現實吧——它有點野孩子。如果您曾經盯著一條沒有任何意義的錯誤訊息,或者花了幾個小時來調試一些完全愚蠢的東西,那麼您就會明白我的意思。然後是 TypeScript。可以把它想像成 JavaScript 的老大哥:用型別來保持事物的直接性。因此,讓我們深入探討為什...
    程式設計 發佈於2024-11-08
  • 冰冷的池塘如何幫助您理解 C++ 中未定義的行為?
    冰冷的池塘如何幫助您理解 C++ 中未定義的行為?
    理解初學者的未定義行為對於新程式設計師來說,未定義行為是一個很難掌握的概念,特別是當他們在工作中遇到它時實踐其具體實施。為了幫助新手理解避免未定義行為的重要性,可以採用一個有效的類比。 想像一個結冰的池塘,其中冰的厚度和穩定性是不可預測的。假設你走過池塘一次,它成立。這能保證每次都能安全通過嗎?當然...
    程式設計 發佈於2024-11-08
  • 在 Go 中使用 WebSocket 進行即時通信
    在 Go 中使用 WebSocket 進行即時通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    程式設計 發佈於2024-11-08
  • JavaScript 能否為不可預測的屬性實現動態 Getter 和 Setter?
    JavaScript 能否為不可預測的屬性實現動態 Getter 和 Setter?
    JavaScript 可以實作動態 Getters/Setters 嗎? 動態 getters 和 setters 允許 JavaScript 物件處理超出預先定義屬性的屬性存取和修改。雖然早期的 JavaScript 技術對已知屬性使用特定的 getter 和 setter,但本文探討了為任何未定...
    程式設計 發佈於2024-11-08
  • 如何在Vue.js元件中動態載入外部JS腳本?
    如何在Vue.js元件中動態載入外部JS腳本?
    在 Vue.js 元件中動態載入外部 JS 腳本使用支付閘道時,整合促進交易的外部腳本變得必要。然而,通常不希望在初始頁面載入時載入這些腳本。這就是 Vue.js 提供的解決方案,用於在特定元件中動態載入外部腳本。 要實現此目的,請利用 Vue.js 元件中的 Mounted() 生命週期掛鉤。 M...
    程式設計 發佈於2024-11-08
  • 如何使用 Foreach 迴圈來尋找 PHP 陣列中的最後一個元素?
    如何使用 Foreach 迴圈來尋找 PHP 陣列中的最後一個元素?
    使用PHP 的foreach 循環查找數組中的最後一個元素在PHP 中,在foreach 循環中訪問數組的最後一個元素需要與Java 相比,這是一種更細緻的方法,可以直接檢查陣列長度。 使用計數和增量要確定最後一個元素,您可以利用count( ) 函數,傳回數組中的元素數量:$numItems = ...
    程式設計 發佈於2024-11-08
  • 如何解決Python中的循環依賴問題?
    如何解決Python中的循環依賴問題?
    Python 中的循環依賴解析在 Python 中,當模組相互依賴其定義時,可能會遇到循環依賴。當兩個檔案(node.py 和 path.py)分別定義類別 Node 和 Path,每個檔案都引用另一個檔案時,就會出現這樣的情況。 最初,path.py 導入 node.py 來存取 Node目的。然...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3