前言
这一章讲了flux和redux,以及react-redux库的作用。可以看书籍的配套代码,理解相关知识。
Flux
各部分作用
- Action
- ActionType定义动作种类
- Actions中导出函数,接收action承载的数据作为参数,调用Dispacher.dispach方法广播动作
- Dispacher
从Flux中导入Dispacher对象,导出一个实例 - Store
- 存储对应组件的数据
- 复制EventEmitter的原型对象,定义getter、on、emit和removeListener
- 定义监听的事件名称,比如’change’
- 调用dispacher.register方法,获取token。该方法接收一个action,根据action.type处理不同逻辑并emit事件
- View
- 从Store中取数据
- 装载时设置监听事件回调函数
- 卸载时取消事件监听函数
- 按钮等动作触发时调用Action中定义的方法
Redux
各部分作用
- Action
- ActionType定义动作种类
- Actions中导出函数,接收action承载的数据作为参数,返回action对象
- Reducer
导出一个函数,接收state和action作为参数。根据action.type返回不同的state。如果接收到未定义的action,原样返回state - Store
- 存储对应组件的数据
- 从redux中导入createStore和combineReducers来根据reducer函数和initialValue生成一个store对象,并导出
- View
- 从store.getState()方法中获取state
- 装载时使用store.subscribe()设置监听事件回调函数
- 卸载时使用store.unscribe()取消事件监听函数
- 按钮等动作触发时调用store.dispach(),传入Action中导出的函数作为参数
容器组件和展示组件
容器组件的作用是与store交互,展示组件的作用是渲染。将两个任务分给两种组件能够保证组件功能单一。
原来的单个组件中,生命周期、props和store的交互都不做修改,但是返回值是一个展示组件。
原来用来渲染的state都当作展示组件的props。因此渲染组件需要保证propTypes一致。又因为渲染组件不保存状态,所以只需要重写render函数,返回相应的渲染元素即可。
最终导出的为容器组件。渲染组件对外不可见。
context
使用context能够保证每一个组件都避免导入store,而是通过父级组件传递下来。但是为了防止子组件层间太深,需要使用context的功能。
- 编写Provider组件,store属性,值为导入的store对象;
- 重写getChildContext方法,返回值为context对象,其中包含store属性;
store必须为object类型
1
2
3
4
5
6
7Provider.propTypes = {
store: PropTypes.object.isRequired
}
//与getChildContext对应
Provider.childContextTypes = {
store: PropTypes.object
};组件中,构造函数和super方法的第二个参数都为context,这样组件可以通过this.context.store来调用store;
- 同时组件还需要限制context的类型:
1
2
3container.contextTypes = {
store:PropTypes.object
}
React-Redux
使用react-redux库可以同时解决上面两种问题。
- 可以从react-redux中导入Provider组件
- 组件中,需要定义两个函数:mapStateToProps和mapDispatchToProps
- 渲染组件部分不需要修改,容器组件通过从react-redux中导入的connect函数生成
- 这个函数接收2中的两个函数作为参数,返回一个函数,再以渲染组件为参数返回容器组件
- mapStateToProps代替的是原容器组件从store中获取state的函数,内容没有变化,只是函数名改变。参数有两个,第一个为store.getState()得到的状态,第二个是组件的props;
- mapDispatchToProps接收两个参数,第一个为store.dispach方法,第二个为组件的props。返回值是一个对象,属性为定义的函数名,属性值为一个函数,能够分发动作。
比较之后,区别主要在于:
- 不需要手写Provider组件,且使用方法不同;
- 不需要手写容器组件,有connect函数生成;
- 不需要在容器组件的componentDidMount和componentWillUnmount生命周期中编写subscribe和unsubcribe方法。应该是已经封装好了;
- 需要编写两个函数用来将原容器组件的state和dispach映射到渲染组件的props上。