前言
<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>把子组件更加细化。