30DaysChallenge 是自主性每兩天寫一篇技術相關的部落格
React
Reconciliation 是 React 的演算法
白話一點來說,就是在資料有變動之後,比較前後畫面的差別並決定要不要重新渲染
聽起來好像很簡單,但你知道就算一樣的畫面,他其實是不同的物件嗎?
<div>
<Header />
</div>
<section>
<Header />
</section>
上述例子,我們的 <header />
,前者與後者是不同的獨立新元素
由於父元件(元素)的改變,就會使整個跟著改變
渲染的過程簡要會是
- 當有資料不同時,先比較,進行新的 DOM tree 與舊的 DOM tree 有沒有差別
- 比較過後發現有差別且畫面有進行變更,才會實際影像到真正的 DOM tree
KEY
先前有提到關於 KEY 的用法,我們加上 key 來讓 React 認識元件,可以提升渲染效能
官方的範例
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
什麼時候會進行比對? state 為甚麼不會不見?
React 會在幾個狀況下比對
- 狀態變更 (state)
- 傳入的屬性變更 (props)
- 當某元件的函式執行了 (components function)
產生過後的新元件仍會保持原本的 state,這是因為 state 是存在 React 之中
並不會再被初始化,除非你手動重新整理、或是關掉網頁
React.memo / useMemo
React.memo
雖然 React 會評估 DOM 的差別,但有些地方永遠都一樣
可以使用 React.memo()來讓 react 知道說,如果這個元件沒有改變,忽略其後面的 child
也就是說,這個會讓 React 知道說若比對之後,仍為一樣的元件,就不會進行渲染
但這也會另外造成額外的運算
語法
export default memo(Header)
useMemo
當我們說重新渲染的時候,會讓整個元件裡面的每個東西,包含函式都重新渲染
所以我們的寫的監聽器或是其他函式,每次都會重新生成
因為 object !== object
(詳情: JS Primitive type & Object type)
不管怎麼比較,看起來就是不一樣,就是會重新生成(執行)
React.memo 只能比對原始型別,那就用 useMemo 存放物件吧
用 useMemo 存放
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])
告一段落 09/02