React.memo 筆記與範例

Claire Wei
ClaireWei
Published in
Jul 28, 2022

本文紀錄React.memo的重要概念及使用範例。

一、React.memo重要概念

React.memo與useMemo的差別在於:React.memo 記憶組件;而useMemo 記住計算結果,不需要在每次渲染時都重複執行獲得一樣的結果,可以瀏覽這篇文章,了解更多關於useMemo的概念。

React.memo使用方式及運作規則

const memorizedComponent = React.memo(Component);
export default memorizedComponent;

React.memo 在收到组件后返回一个新组件。當我們談論 React.memo 時,它不是傳統的 memoization。它不會保留之前收到的(數量龐大的)的props。它著重在比較先前的props與收到的props的差異。當兩者不同時才更新。

二、React.memo使用範例

※以下我們使用使用 React DevTools Profiler來紀錄及分析使用React.memo前後的差異:

(1)使用條件-安裝React DevTools Extension在您的瀏覽器中,且專案為React 16.5 或更高版本建構。

(2)使用方法-開啟開發人員工具(Developer tools)面板,點選Profiler ,點選 Start profiling 錄製,執行欲錄製的動作後(如: 新增一個todo),停止錄製。

(一)程式碼

1.TodoItem.js使用React.memo前:

※在錄製新增todo的過程後我們得到以下結果,點開TodoList 可以看到所有TodoItem被重新渲染。

使用React.memo前

2.如何使用React.memo優化Part1

// TodoItem.js
const memorizedTodoItem = React.memo(TodoItem);
export default memorizedTodoItem;

※重新錄製新增todo的過程後我們得到以下結果,可以看到最後階段所有組件才被重新渲染。

使用React.memo優化Part1

有比原先的結果好,但為什麼到最後階段還是全部組件會重新渲染呢?原因在於React.memo 執行的是shallow comparison,當我們再次創建該待辦事項列表時,會獲得新的references,相當於產生一個新列表,因此會再次創建所有項目。那要如何才能達到預期的只渲染新創建的組件?

3.如何使用React.memo優化Part2 (TodoItem.js使用React.memo後)

// TodoItem.js
const areEqual = (prevProps, nextProps) => {
 return (
  prevProps.todo.id === nextProps.todo.id &&
  prevProps.todo.completed === nextProps.todo.completed
 );
};
const memorizedTodoItem = React.memo(TodoItem, areEqual);
export default memorizedTodoItem;
// 調用 areEqual 函數來比較, 查看Object中的primitive value。

※重新錄製新增todo的過程後我們得到以下結果,可以看到過程中只有渲染創建的組件🎉🎉🎉

使用React.memo優化Part2

當我們瞭解更多可以優化的方法後,回頭看之前寫的程式碼總會發現可以更好的地方,也會對正在開發的專案產生不夠完美的想法,不過比起立馬投入修改,現在的習慣傾向於記錄下來,等初步建構完專案之後統整性檢視及優化,避免自己過於糾結,也更能依優化前後的影響程度來決定優先順序。

三、推薦影片

What is React.memo — It’s not useMemo

--

--