[译] 3 条简单的 React 状态管规则

栏目: IT技术 · 发布时间: 4年前

内容简介:2019年第13期

[译] 3 条简单的 React 状态管规则

2019年第13期

[译] 3 条简单的 React 状态管规则

React组件内部的状态是在渲染之间保持不变的封装数据。 useState() 是React钩子,负责管理功能组件内部的状态。

我喜欢 useState() 确实使状态处理变得非常容易。但是我经常遇到类似的问题:

  • 我应该将组件的状态划分为小状态,还是保持复合状态?

  • 如果状态管理变得复杂,我应该从组件中提取它吗?怎么做?

  • 如果 useState() 用法是如此简单,那么何时需要 useReducer()

这篇文章介绍了3条简单的规则,可以回答上述问题并帮助您设计组件的状态。

一个关注点

高效状态管理的首要原则是: 让一个状态变量负责一个关注点。

让一个状态变量负责一个关注点使它符合单一责任原则。让我们来看一个复合状态的例子,即一个包含多个状态值的状态。

[译] 3 条简单的 React 状态管规则

状态由一个普通的JavaScript对象组成,该对象具有属性 oncount

第一个属性 state.on 包含一个布尔值,表示开关。 state.count 保存一个表示计数器的数字,例如,用户单击按钮的次数。

然后,假设您要将计数器增加1:

[译] 3 条简单的 React 状态管规则

您必须将整个状态保持在附近才能更新计数。这是一个需要调用的大型构造来简单地增加一个计数器:因为一个状态变量负责两个关注点:开关和计数器。

解决方案是将复合状态分成2个原子状态并计数:

[译] 3 条简单的 React 状态管规则

on 状态变量仅负责存储开关状态。同样的方法, count 变量仅负责计数器。

现在,让我们尝试更新计数器:

[译] 3 条简单的 React 状态管规则

计数状态仅负责计数,易于推理,分别易于更新和读取。

不必担心调用多个 useState() 为每个关注点创建状态变量。

但是请注意,如果您过多使用 useState() 变量,则很有可能您的组件违反了“单一职责原则”。只需将此类组件拆分为较小的组件即可。

提取复杂的状态逻辑

将复杂的状态逻辑提取到自定义钩子中。

将复杂的状态操作保留在组件中是否有意义?

创建React Hook是为了将组件从复杂的状态管理和副作用中隔离出来。因此,由于组件应该只关心要呈现的元素和要附加的一些事件侦听器,所以应该将复杂的状态逻辑提取到自定义Hook中。

让我们考虑一个管理产品列表的组件。用户可以添加新的产品名称。约束是产品名称必须唯一。

第一次尝试是将产品名称列表的设置程序直接保留在组件内部:

[译] 3 条简单的 React 状态管规则

names 变量保存产品名称,单击Add按钮时将调用 addNewProduct() 事件处理程序。

addNewProduct() 中,使用一个 Set 对象来保持产品名称的唯一性。组件应该关注这个实现细节吗?不。

最好将复杂的状态设置器逻辑隔离到自定义Hook中。

新的自定义Hook useUnique() 负责保持项目的唯一性:

[译] 3 条简单的 React 状态管规则

将自定义状态管理提取到一个Hook后, ProductsList 组件就变得轻松多了:

[译] 3 条简单的 React 状态管规则

const [names, addName] = useUnique([]) 是启用自定义Hook的原因。组件不再与复杂的状态管理混杂在一起。

如果您想在列表中添加新名称,则只需调用 add('新产品名称')

最重要的是,将复杂的状态管理提取到自定义Hook中的好处是:

  • 组件不再需要状态管理细节

  • 自定义钩子可以重用

  • 可以很容易地在隔离状态下测试自定义Hook

提取多个状态操作

将多个状态操作提取到一个reducer中。

继续使用 ProductsList 的示例,让我们添加一个 Delete 操作,该操作从列表中删除一个产品名称。

现在,您必须编码2个操作:添加和删除产品。处理这些操作,就可以创建一个 reducer 并使组件摆脱状态管理逻辑。

这种方法也符合 hook 的思想:从组件中提取复杂的状态管理。

这是添加和删除产品的 reducer 的可能实现:

[译] 3 条简单的 React 状态管规则

然后可以通过调用 React 的  useReducer()  Hook 在产品列表中使用 uniqueReducer()

[译] 3 条简单的 React 状态管规则

const [names, dispatch] = useReducer(uniqueReducer,[]) 启用了uniqueReducer。 names 是保存产品名称的状态变量, dispatch 是要使用操作对象调用的函数。

单击添加按钮后,处理程序将调用 dispatch({type:'add',name:newName}) 。调度添加操作使减速器 uniqueReducer 向状态添加新产品名称。

同样,单击“删除”按钮时,处理程序将调用 dispatch({type:'delete',name}) 。调度删除操作会将产品名称从名称状态中删除。

总结

状态变量应该负责一个关注点。

如果状态具有复杂的更新逻辑,则将该逻辑从组件中提取到自定义Hook中。

同样,如果状态需要多个操作,请使用 reducer 合并这些操作。

无论您使用什么规则,状态都应尽可能简单和分离。该组件不应被状态更新的细节所困扰:它们应该是自定义Hook或 reducer 的一部分。

严格遵循这3个简单规则将使您的状态逻辑易于理解、维护和测试。

原文:https://dmitripavlutin.com/react-state-management/

[译] 3 条简单的 React 状态管规则

全文完

访问带链接版请点击阅读原文

往期精彩回顾   

聚焦 大前端 技术和 成长 的公众号

关注我的公众号,第一时间接收原创、精选干货文章

[译] 3 条简单的 React 状态管规则

[译] 3 条简单的 React 状态管规则


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

马尔可夫链:模型、算法与应用

马尔可夫链:模型、算法与应用

Wai-Ki Ching、Ximin Huang / 陈曦 / 清华大学出版社 / 2015-6 / 39

《马尔可夫链:模型、算法与应用 应用数学译丛》讲述了马尔可夫链模型在排队系统、网页重要性排名、制造系统、再制造系统、库存系统以及金融风险管理等方面的最新应用进展.全书共安排8章内容,第1章介绍马尔可夫链、隐马尔可夫模型和马尔可夫决策过程的基本理论和方法,其余7章分别介绍马尔可夫链模型在不同领域中的应用. 《马尔可夫链:模型、算法与应用 应用数学译丛》可作为自动化、工业工程、统计学、应用数学以及管理......一起来看看 《马尔可夫链:模型、算法与应用》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试