Redux
// 更新全局状态是 react app 需要重新 render 整个 app?性能有问题?
Redux 是 JavaScript 应用程序的可预测状态容器。
回顾 flux:
View: 视图层 Action(动作):视图层发出的消息(比如mouseClick) Dispatcher(派发器):用来接收Actions、执行回调函数 Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面
==============
单一数据源: 整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
当需要拆分数据处理逻辑时,应该使用 reducer 组合 而不是创建多个 store。
State 是只读的: 惟一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
store.dispatch(action) // 将更新state,之后component.setState(newState)更新组件
切换一个菜单需要2步, 第一步做切换 ui 的动作,第二步异步拿到数据后做更新数据的动作
使用纯函数(对同一个输入有相同输出)来修改执行: 为了描述 action 如何改变 state tree ,你需要编写 reducers(纯函数)。
它接收先前的 state 和 action,并返回新的 state
将模型的更新逻辑全部集中于这层
正确且简便的方式是,你应该在 reducer 中返回一个新对象来更新 state
可以写很多 reducer 来处理 state 中的一部分,最后由一个函数(combineReducers)组合返回state
combineReducers 的参数是一个函数,收到 state 中与该函数同名的属性作为其reducer的子state,同时收到第二个参数 action
Redux store 保存了根 reducer 返回的完整 state 树
action 的结构使用类似 http 响应:
type 必须,一个字符串或者符号
payload 其它的任何信息
meta 类型属性的补充说明,类似http中的header
error 表明payload 是否为错误对象
Store 就是把 action 和 reducer 联系到一起的对象。Store 有以下职责:
- 维持应用的 state;
- 提供 getState() 方法获取 state;
- 提供 dispatch(action) 方法更新 state;
- 通过 subscribe(listener) 注册监听器;
- 通过 subscribe(listener) 返回的函数注销监听器。
===== 配合react
明智的做法是只在最顶层(如路由操作)组件里使用 Redux。其余内部组件仅仅是展示性的,所有数据都通过 props 传入。
容器组件 | 展示组件 | |
Location | 最顶层,路由处理 | 中间和子组件 |
Aware of Redux | 是 | 否 |
读取数据 | 从 Redux 获取 state | 从 props 获取数据 |
修改数据 | 向 Redux 派发 actions | 从 props 调用回调函数 |
要理解 connect 是如何工作的,最重要的是要先理解以下2点:1. React 的 context2. Provider 的工作原理其实很多人都不知道 React 有 context,毕竟平时真的很少用的到。也就是说 child components(可以是多层嵌套)能拿到 parent component 定义的 context。也就是说,只要 parent component 定义了context,那么可以不必通过props层层传递,就能直接在 child components 拿到。Provider 恰恰是利用这一特性,通过 Provider component 将 store 放置在 parent 的 context。很简单,整个 Provider 的源码也就20多行。既然现在所有child component都能通过context拿到store了,那connect就很好理解了。connect就是返回一个 wrapped componnet,这个component会通过获取context的store,来和store中的数据进行"链接"。connect方法的内部实现稍微复杂一点,但是有一点,connect会用 shallow compare来比较"state",来决定是否更新,所以如果你的state tree是deep nested的话,这里是会有一定的时间消耗的。