传统mvc 模型
model 与 view 之间的双向对话, 让数据和状态管理变的复杂
Redux (Flux + reducer)
基于Flux 单向数据流的状态管理框架
- 单向数据流
- 唯一数据源 (Store)
- 保持状态只读
- 数据改变只能通过纯函数完成(Reducer)
Action
- 行为的抽象
- 普通的JS 对象
- 必须有一个type
- 一般由方法生成
1 | // Action |
Reducer
响应的抽象,只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。 (previousState, action) => newState1
2
3
4
5
6
7
8
9
10
11// Reducer
function counter(state = { count: 0 }, action) {
const count = state.count
switch (action.type) {
case 'increase':
return { count: count + 1 }
default:
return state
}
}
export default todos
Store
状态树, 状态的“数据库”,
Store 有以下职责:
- 维持应用的 state;
- 提供 getState() 方法获取 state;
- 提供 dispatch(action) 方法更新 state;
- 通过 subscribe(listener) 注册监听器;
- 通过 subscribe(listener) 返回的函数注销监听器
1 | // Store |
container 与 component 区分
component: UI组件
不含有状态,UI 组件又称为”纯组件”,即它纯函数一样,纯粹由参数决定它的值
container: 容器组建
- 负责管理数据和业务逻辑,不负责 UI 的呈现
- 带有内部状态
- 使用 Redux 的 API
connect 用于从UI组件生成容器组件
connect方法接受两个参数:mapStateToProps和mapDispatchToProps
- (1)输入逻辑:外部的数据(即state对象)如何转换为 UI 组件的参数
- (2)输出逻辑:用户发出的动作如何变为 Action 对象,从 UI 组件传出去。
mapStateToProps()
mapStateToProps是一个函数。它的作用就是像它的名字那样,建立一个从(外部的)state对象到(UI 组件的)props对象的映射关系。
1 | // Map Redux state to component props |
connect方法可以省略mapStateToProps参数,那样的话,UI 组件就不会订阅Store,就是说 Store 的更新不会引起 UI 组件的更新。
mapDispatchToProps()
mapDispatchToProps是connect函数的第二个参数,用来建立 UI 组件的参数到store.dispatch方法的映射。也就是说,它定义了哪些用户的操作应该当作 Action,传给 Store。它可以是一个函数,也可以是一个对象。1
2
3
4
5
6// Map Redux actions to component props
function mapDispatchToProps(dispatch) {
return {
onIncreaseClick: () => dispatch(increaseAction)
}
}
provider 组件
connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数。
一种解决方法是将state对象作为参数,传入容器组件。但是,这样做比较麻烦,尤其是容器组件可能在很深的层级,一级级将state传下去就很麻烦。React-Redux 提供Provider组件,可以让容器组件拿到state
1 | <Provider store={store}> |
实例
1 | import React, { Component } from 'react' |