本博客 hjy-xh,转载请申明出处
说明
Redux是一个使用叫做action的事件来管理和更新应用状态的模式和工具库,它以集中式Store的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。
三大原则
单一的数据源
整个应用的state被存储在一棵object tree中,并且这个object tree只存在于唯一一个store中State 是只读的
改变state的方法就是触发action,action是一个用于描述已发生事件的普通对象使用纯函数来执行修改
为了描述action如何改变state tree,需要编写reducers
一些重要的概念
Action
Action是把数据从应用传到store的有效载荷。它是store数据的唯一来源- 一般来说会通过
store.dispatch()将action传到store Action本质上JavaScript普通对象,约定action内必须使用一个字符串对象type字段来表示将要执行的动作
Action创建函数
Action创建函数就是生成action的方法,这样做将使action创建函数更容易被移植和测试
1
2
3
4
5
6function addTodo(text) {
return {
type: ADD_TODO,
text
}
}Reducer
Reducers指定了应用状态的变化如何响应actions并发送到store的,记住actions只是描述了有事情发生了这一事实,并没有描述如何更新statereducer就是一个纯函数,接收旧的state和action,返回新的state:(previousState, action) => newState
Store
Store有以下职责:- 维持应用的
state - 提供
getState()方法获取state - 提供
dispatch(action)方法更新state - 通过
subscribe(listener)注册监听器,并能够能够其返回的函数注销监听器
- 维持应用的
Middleware
相对于Express或者Koa的middleware,Redux middleware被用于解决不同的问题,但其中的概念是类似的。它提供的是位于action被发起之后,到达reducer之前的扩展点。 你可以利用Redux middleware来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。
数据流
Redux使用单向数据流
State描述了应用程序在特定时间点的状况- 基于
state来渲染UI - 当发生某些事情时(例如用户点击按钮),
state会根据发生的事情进行更新 - 基于新的
state重新渲染UI
将这些步骤分解为更详细的内容:
初始启动
- 使用最顶层的 root reducer 函数常见 Redux store
- store 调用一次root reducer,并将返回值保存为它的初始 state
- 当UI首次渲染时,UI组件访问 Redux store 的当前 state,并使用该数据来决定要呈现的内容。同时监听 store 的更新,以便它们可以知道 state 是否已更改
更新环节
- 应用程序中发生了某些事情,例如用户点击按钮
- dispatch 一个 action 到 React store
- store 用之前的 state 和当前的 action 再次运行 reducer 函数,并将返回值保存为新的 state
- store 通知所有订阅过的UI,通知它们 store 发生更新
- 每个订阅过 store 数据的UI组件都会检查它们需要的 state 部分是否被更新
- 发现数据被更新的每个组件都强制使用新数据重新渲染,紧接着更新网页
一些疑问
Reducer的规则
Reducer必须符合以下规则:
仅使用
state和action参数计算新的状态值禁止直接修改state。必须通过复制现有的state并对复制的值进行更改的方式来做不可变更新
禁止任何异步逻辑、依赖随机值或导致其它副作用的代码
为什么这些规则很重要?
Redux的目标之一是使代码可预测。当函数的输出仅根据输入参数计算时,更容易理解该代码的工作原理并对其进行测试
如果一个函数依赖于自身之外的变量,或者行为随机,你永远不知道运行时它会发生什么
如果一个函数 mutate 了其它对象,比如它的参数,这可能会意外地改变应用程序的工作方式
Redux DevTools 的一些功能取决于你的 reducer 是否正确遵循这些规则