如何存储 React 中的数据和状态
四种 React 组件存放数据的方式
State
-
作用范围:
当数据不参与 dataFlow 时可以考虑使用。
存储 UI 的状态而不是数据。将 UI 的状态及一些临时的数据保存。
当组件的展示内容会随之改变时,可以将数据放在 state 里,即涉及到 UI 的变化。
-
注意事项:
只有 class 组件可以使用。
state 改变时,会 re-render 组件,除非 shouldComponentUpdate() 返回 false。
state 中的数据只影响当前组件,除非将 state 作为 props 传给子组件。
不能直接修改 state,state 的更新可能是异步的。setState
this
-
注意事项:
this 上存放的数据的改变不会引起 re-render。
任何情况都可以使用,无论是 class 还是 function
注意 this 的绑定,通过 bind 或箭头函数=>
Static
-
作用范围:
可以直接通过 class 的名字访问,并且不会 re-render。作用于当前组件,同类型组件共享这个数据。
-
实例:
react 组件中,propTypes 和 defaultProps 可以提高代码可读性和组件强壮性。这两个属性就是 static 类型的。
Store
-
作用范围:
任何组件,用来进行组件间的数据交互。存储多个组件之间共享的数据。存储组件的状态而不是 UI 的状态,例如登录态。
store 是存放数据的 state 和处理数据的一些方法的集合。state 只读,通过 store 提供的方法修改,修改的方法应该是纯函数。通过 dispatch 一个 action , 然后由 reducer 处理。
Props
-
写在 JSX 标签上,给子组件添加属性,传递给子组件的 props
-
注意事项:
key 和 ref 不会传递给子组件的 props
子组件内部不能改变 this.props 的值
状态管理
逻辑和交互
从逻辑和交互的角度来分析整个应用的状态,可以分为领域状态和视图状态两种。
从应用的功能逻辑上,可以拆出一个概念,叫领域状态,用来描述,处理实际应用功能的各种情况。比如在文件上传中,区分文件上传进度,上传成功,上传失败等各种情况,是业务的逻辑。
如果要测试,也是基于领域状态来编写测试。
目前使用的前端应用框架,比如 React,官网上是这样描述的:“用于构建用户界面的 JavaScript 库”。基于领域逻辑,来开发整个应用的视图交互,在构建界面的时候会涉及很多组件在显示上的状态,比如 loading,打开关闭的状态等,被称为视图状态。
数据如何存放,何时使用状态管理?
大多数视图库是以组件为模块边界的,组件中的逻辑,有些是受其他的组件影响的,并不一定是完全自己就可以控制的。
各种状态到底该如何管理,要存放在哪里?
我们可以从以下几个方向去考虑:
视图状态
- 完全受当前组件控制,不受其他组件影响。 ----自己组件内管理
- 组件间互相影响,要根据应用复杂度,组件间的跨度决定如果跨度比较近,则存放在共同父组件如果跨度相对较远且应用不复杂,可以把状态提升到共同的 Context 中如果应用复杂,再考虑使用状态管理方案
领域状态
对于业务的各种逻辑状态,本来就是分布在不同的组件中的。
- 简单的小应用可以任其分布在组件中,或者提升到共同的 Context 中。
- 其他的情况,推荐使用状态管理,比如 Redux,Vuex,mobx。
切勿一股脑将所有状态都交给 Redux 处理,杀鸡焉用宰牛刀。全部由 Redux 处理是可行的,但是会影响项目的可读性,扩展性和性能。
甚至,对于领域状态中的子领域,可以在有状态管理方案的基础上再抽象出来单独处理。
比如对于服务端请求的数据这一领域状态,其性质更类似于缓存,在 React 中可以使用 SWR 或 React Query 处理。