提升效能最有效的方式就是減少render()被call的次數
render後產生virtual dom若react拿virtual跟真實dom比較後有不同則更新 <-費時
parent change 只要parent rerender則必觸發child rerender
state/context change
props change會不會觸發rerender,props若有變是因為parent去update他,
此時parent會rerender,所以會觸發child rerender,並不是props改變觸發rerender)
hooks change (e.g. hook內state change)
善用react-dev-tool(chrome套件)的profiler,它可以告訴你為何這個component rerender
children也是prop,可以將B(component)作為prop往下傳再render它,來減少 B render的次數(因為prop改變不會觸發rerender):
<A><B/></A> == <A children={B}></A>
state往下放(減少上層Component 因state change而rerender)
笨重component跟他用到的state往下包:
useMemo讓該component只有在關注的state改變時才會rerender (value或component都可以memo) 對parent memo 無法讓child不rerender
承上: 不要在在component裡宣告component,因為每次parant rerender都會重做一次 (解:可以用useMemo包起來
memoize prop不會防止rerender 要memo整個child component
useMemo + effect 組合技 減少effect觸發
memo耗時的計算結果 e.g. memo一個很大的component
把context拆細一點 減少不必要context觸發一大堆component更新
承上: memo + context 組合技 減少不必要context更新觸發rerender
使用map render list時 key作為每個item的id若key不變但內容變則react不會幫你重render
最好用他的uniqueID當key
別用prop當state初始值
若props變了但該component並未重新render則state的初始不會是新的
請直接用該prop或加useEffect(對應週期:componentWillReceiveProps)
善用PureComponent:
PureComponent採用shallow compare
(最多只會檢查到物件的第一層)檢查input是否相同,
若input相同則不rerender
善用React.memo: React.memo()
props變時A才會rerender(若該component有state改變則還是會rerender)
別在render裡宣告inline function
因為inline function 會在檢查時({} !== {}) 失敗而觸發rerender
不好: <A onClick={(e)=>console.log(e)}>
好: <A onClick={print}>
更新state跟props時一律使用immutable data
使用immutable data(創一個新的讓新的跟舊的比)可以讓compare不出錯
data immutability 是一種 coding style:
Whenever your object would be mutated, don’t do it. Instead, create a changed copy of it.
在setState(setState是非同步的)後使用該值會是舊的
使用<React.Fragment>或是<></>當wrapper避免多長html
使用 react-window/react-virtualized 處理大長list
分production跟development flag
https://www.developerway.com/posts/react-re-renders-guide
https://blog.techbridge.cc/2018/01/05/react-render-optimization/
https://www.codementor.io/blog/react-optimization-5wiwjnf9hj