React.memo 筆記與範例
本文紀錄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被重新渲染。
2.如何使用React.memo優化Part1
// TodoItem.js
const memorizedTodoItem = React.memo(TodoItem);
export default memorizedTodoItem;
※重新錄製新增todo的過程後我們得到以下結果,可以看到最後階段所有組件才被重新渲染。
有比原先的結果好,但為什麼到最後階段還是全部組件會重新渲染呢?原因在於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的過程後我們得到以下結果,可以看到過程中只有渲染創建的組件🎉🎉🎉
當我們瞭解更多可以優化的方法後,回頭看之前寫的程式碼總會發現可以更好的地方,也會對正在開發的專案產生不夠完美的想法,不過比起立馬投入修改,現在的習慣傾向於記錄下來,等初步建構完專案之後統整性檢視及優化,避免自己過於糾結,也更能依優化前後的影響程度來決定優先順序。
三、推薦影片