轻松渲染优化:使用React Hooks进行state跟踪

2019 年 7 月 27 日

轻松渲染优化:使用React Hooks进行state跟踪

介绍


React useContext 使用起来非常方便,它可以访问定义 DOM 树中多个组件的全局状态或共享状态。


但是,useContext 不是专为全局状态设计的,并且有一个警告:对上下文值的任何更改都会多播,导致所有 useContext 重新渲染组件。


这篇文章展示了一些关于问题的示例代码以及具有 state 使用跟踪的解决方案。


问题定位


我们以人为对象来举例说明。


const initialState = {  firstName: 'Harry',  familyName: 'Potter',};
复制代码


我们使用上下文和 local state。


const PersonContext = createContext(null);
const PersonProvider = ({ children }) => { const [person, setPerson] = useState(initialState); return ( <PersonContext.Provider value={[person, setPerson]}> {children} </PersonContext.Provider> );};
复制代码


最后,这是一个显示人物名字的组件。


const DisplayFirstName = () => {  const [person] = useContext(PersonContext);  return (    <div>First Name: {person.firstName}</div>  );};
复制代码


到现在为止还挺好。


但是,问题是当你更新此人的 family name 的同时,它将触发 DisplayFirstName 重新渲染,甚至渲染结果都是相同的。


请注意,这是不是一个真正的问题,直到它成为一个问题。 通常情况下,大多数较小的应用程序都可以正常运行,但是一些较大的应用程序会产生性能问题。


解决方案


让我们看看状态使用跟踪如何解决这个问题。


provider 看起来有点不同,但代码基本相同。


const usePerson = () => useState(initialState);const { Provider, useTracked } = createContainer(usePerson);
const PersonProvider = ({ children }) => ( <Provider> {children} </Provider>);
复制代码


DisplayFirstName 组件像这样更改。


const DisplayFirstName = () => {  const [person] = useTracked();  return (    <div>First Name: {person.firstName}</div>  );};
复制代码


注意这个变化? 只有区别是 useTracked()而不是 useContext(…)。


通过这个小的更改,跟踪 DisplayFirstName 中的状态使用情况。 现在,即使更新了 family name,只要 first name 未更新,该组件就不会重新渲染。


这是轻松的渲染优化。


高级示例


有些读者可能会认为也可以通过类似 useSelector 的 hooks API 来实现。


这是另一个使用 useTracked 的例子。


const initialState = {  firstName: 'Harry',  familyName: 'Potter',  showFullName: false,};
复制代码


假设我们有一个像上面这样的 state ,让我们创建一个带有条件的组件。


const DisplayPersonName = () => {  const [person] = useTracked();  return (    <div>      {person.showFullName ? (        <span>          Full Name: {person.firstName}          <Divider />          {person.familyName}        </span>      ) : (        <span>First Name: {person.firstName}</span>      )}    </div>  );};
复制代码


此组件将在两个场景中重新渲染。


a)当更新 firstName 或 familyName 时,显示全名。


b)当更新 firstName 时,不显示全名。


使用 useSelector 重现相同的行为并不容易,最终可能会在组件中分开。


使用状态来进行跟踪的项目


有两个项目使用状态来跟踪。


  1. reactive-react-redux:https://github.com/dai-shi/reactive-react-redux


这是 react-redux 的替代库。 它具有相同的 hooks API 和 useTrackedState hook。


  1. react-tracked:

  2. https://github.com/dai-shi/react-tracked


这是一个没有 Redux 依赖的库。 本文中的示例基于此。 它具有兼容的 hooks API 和 reactive-react-redux。


结束


这篇文章重点介绍了如何轻松使用状态跟踪。 篇幅限制,我们并没有讨论这些类库的具体实现。简而言之,我们使用 Proxy API 来跟踪状态使用情况。 我们还在 Context API 中使用未记录的功能来停止广播。 如果你对这些细节感兴趣,请查看如上所述的 GitHub 库。


2019 年 7 月 27 日 16:3410254
用户头像
王文刚 Instagram 营销专家

发布了 37 篇内容, 共 17.6 次阅读, 收获喜欢 50 次。

关注

评论

发布
暂无评论
发现更多内容

百度主任架构师谭待:打造非职权技术管理机制

TGO鲲鹏会

聊聊分心这件事

Jackey

Doris 一种实时多维分析的解决方案

迹_Jason

大数据

基于RocketMQ实现分布式事务 - 完整示例

清幽之地

Java 分布式事务 RocketMQ 微服务

字节跳动的增长密码

池建强

字节跳动 张一鸣

NVidia Docker介绍

薛磊

Docker

3000w人民币的学费——我的决策反思

孤岛旭日

数据中台 架构 中台 企业中台 企业架构

【JAVA】感受下JDK14的空指针提示

遇见

Java jdk jep

redis数据结构介绍-第一部分 SDS,链表,字典

Nick

redis 源码 数据结构 源码分析 算法

中台之路,从平台到中台的思考与实践(一)

孤岛旭日

架构 中台 企业中台 企业架构

中台之路,从平台到中台的思考与实践(二)

孤岛旭日

架构 中台 企业中台 企业架构

ELF文件格式

韩超

Gitlab CI/CD 中的 Cache 机制

Chong

DevOps gitlab cicd

苏宁云商向江旭:是时候让技术成为新司机了!

TGO鲲鹏会

自动驾驶复苏在2020

陈思

人工智能 自动驾驶

开源这件事儿,越来越“声势浩大”了

赵钰莹

Apache GitHub 阿里巴巴 开源 腾讯

NVidia-Docker2 性能优化

薛磊

Docker gpu nvidia container

人间至味——苦瓜

三只猫

人生 美食 生活

ArrayList、LinkedList 你真的了解吗?

Damon

Java

Kylin 实时流处理技术探秘.笔记

迹_Jason

大数据

从西游到武侠——确定性与不确定性

伯薇

个人成长 管理 确定性 不确定性

特定系统的Linux的构建

韩超

服务降级的常见套路

松花皮蛋me

Java

Docker Swarm 踩坑

ikook

Docker Docker Swarm 技术 容器 踩坑

程序员通过哪些方式来赚钱?

一尘观世界

程序员 外包 自由职业 副业 赚钱

我使用了哪些生产力工具?

ikook

效率工具 软件 Alfred Notion 推荐

面试官,不要再问我三次握手和四次挥手

猿人谷

面试 TCP 三次握手 四次挥手

高手和普通人的差距,不看不知道,一看吓一跳

熊斌

学习

[KubeFlow] MPI-Operator深度解读

薛磊

Docker gpu kubeflow Kubernetes

纯技术改造,技术如何驱动需求,我有话说

一叶而不知秋

项目管理 架构 技术

Linux的proc文件系统编程

韩超

轻松渲染优化:使用React Hooks进行state跟踪-InfoQ