不要将数据结构误认为状态结构

当你构建 React 表单时,通常会将所有内容组合成一个巨大的状态对象。

你在 UI 中看到一个“地址”部分。于是你在状态中创建了一个地址对象。它看起来井然有序,看起来很整洁。

这是一个陷阱。

问题不在于 React,而在于你的状态结构。

表单不是静态数据,而是交互式系统。用户不会按“部分”来更新表单,而是按“字段”来更新。

为什么嵌套状态会损害你的项目:

  • 更新变得沉重。为了修改一个城市名称,为了保持不可变性(immutability),你必须重新创建城市对象、地址对象以及顶层的表单对象。
  • 复杂度泄露。随着表单的增长,你的校验和渲染逻辑会变得越来越难以管理。
  • 重渲染增加。修改一个嵌套值会创建新的对象引用。这可能会触发整个组件树中不必要的更新。
  • 心智负担增加。你不再思考用户,而是开始思考对象路径。

小型表单比较宽容,但产品级表单则不然。

生产环境中的表单需要校验、自动保存和条件逻辑。如果你在深层嵌套的对象之上构建这些功能,每一个新功能的开发成本都会变得非常高。

解决方案是围绕“数据如何变化”来设计状态,而不是围绕“它看起来如何”来设计。

扁平化的状态结构具有以下优势:

  • 更新更快。修改单个值时需要改动的代码更少。
  • 更易于调试。更新保持局部性且可预测。
  • 更好的组件边界。你可以传递小块数据,而不是庞大的对象。

不要盲目地扁平化一切。如果数据很少变化且总是同步移动,那么嵌套是可以接受的。但不要将表单中那些频繁变化的部分进行嵌套。

在编写代码之前,问自己以下问题:

  • 哪些字段变化最频繁?
  • 哪些部分需要独立的校验?
  • 哪些更新必须与 UI 的其他部分保持隔离?

如果更新一个字段感觉比修改本身还要困难,那么你的状态结构就是问题所在。

不要再根据 UI 来建模你的状态,要开始根据用户的行为来建模。

来源:https://dev.to/hardik_kuwar_7caa4626bb16/the-mistake-is-assuming-data-shape-and-state-shape-should-always-match-5g0e