介绍
React useContext 使用起来非常方便,它可以访问定义 DOM 树中多个组件的全局状态或共享状态。
但是,useContext 不是专为全局状态设计的,并且有一个警告:对上下文值的任何更改都会多播,导致所有 useContext 重新渲染组件。
这篇文章展示了一些关于问题的示例代码以及具有 state 使用跟踪的解决方案。
问题定位
我们以人为对象来举例说明。
我们使用上下文和 local state。
最后,这是一个显示人物名字的组件。
到现在为止还挺好。
但是,问题是当你更新此人的 family name 的同时,它将触发 DisplayFirstName 重新渲染,甚至渲染结果都是相同的。
请注意,这是不是一个真正的问题,直到它成为一个问题。 通常情况下,大多数较小的应用程序都可以正常运行,但是一些较大的应用程序会产生性能问题。
解决方案
让我们看看状态使用跟踪如何解决这个问题。
provider 看起来有点不同,但代码基本相同。
DisplayFirstName 组件像这样更改。
注意这个变化? 只有区别是 useTracked()而不是 useContext(…)。
通过这个小的更改,跟踪 DisplayFirstName 中的状态使用情况。 现在,即使更新了 family name,只要 first name 未更新,该组件就不会重新渲染。
这是轻松的渲染优化。
高级示例
有些读者可能会认为也可以通过类似 useSelector 的 hooks API 来实现。
这是另一个使用 useTracked 的例子。
假设我们有一个像上面这样的 state ,让我们创建一个带有条件的组件。
此组件将在两个场景中重新渲染。
a)当更新 firstName 或 familyName 时,显示全名。
b)当更新 firstName 时,不显示全名。
使用 useSelector 重现相同的行为并不容易,最终可能会在组件中分开。
使用状态来进行跟踪的项目
有两个项目使用状态来跟踪。
reactive-react-redux:https://github.com/dai-shi/reactive-react-redux
这是 react-redux 的替代库。 它具有相同的 hooks API 和 useTrackedState hook。
react-tracked:
这是一个没有 Redux 依赖的库。 本文中的示例基于此。 它具有兼容的 hooks API 和 reactive-react-redux。
结束
这篇文章重点介绍了如何轻松使用状态跟踪。 篇幅限制,我们并没有讨论这些类库的具体实现。简而言之,我们使用 Proxy API 来跟踪状态使用情况。 我们还在 Context API 中使用未记录的功能来停止广播。 如果你对这些细节感兴趣,请查看如上所述的 GitHub 库。
评论