前言
<code>createContext</code>是 react 提供的用于全局狀态管理的一個 api,我們可以通過<code>Provider</code>元件注入狀态,用<code>Consumer</code>元件或者<code>useContext</code>api 擷取狀态(推薦使用<code>useContext</code>方式,更加簡潔)。
<code>createContext</code>讓元件間的通信更為友善,但如果使用不當卻會帶來很大的性能問題。下面我們會讨論引起性能問題的原因以及如何優化。
性能問題的根源
先來看一個例子:createContext性能問題原因,注意例子中的2個問題點。
從這個例子可以看出來,用<code>ThemeCtx.Provider</code>直接包裹子元件,每次<code>ThemeCtx.Provider</code>元件渲染會導緻所有子元件跟着重新渲染,原因是使用<code>React.createElement(type, props: {}, ...)</code>建立的元件,每次<code>props: {}</code>都會是一個新的對象。
<code>createContext</code>是根據釋出訂閱模式來實作的,<code>Provider</code>的<code>value</code>值每次發生變化都會通知所有使用它的元件(使用<code>useContext</code>的元件)重新渲染。
解決方案
上面我們分析了問題的根源,下面就開始解決問題。 同樣先看一下優化後的例子:createContext性能優化。
把<code>ThemeContext</code>抽離出來,子元件通過<code>props</code>的<code>children</code>屬性傳遞進來。即使<code>ThemeContext.Provider</code>重新渲染,<code>children</code>也不會改變。這樣就不會因為<code>value</code>值改變導緻所有子元件跟着重新渲染了。
通過上面的方式可以一刀切的解決整體重複渲染的問題,但局部渲染的問題就比較繁瑣了,需要我們用<code>useMemo</code>一個個的修改子元件,或者使用<code>React.memo</code>把子元件更加細化。