Redux流程图
React和Redux分工
React-Redux将所有组件分为了UI组件和容器组件。
UI组件不带任何逻辑,只负责渲染,所有的数据都通过this.props
提供。(由React负责)
容器组件负责数据管理和业务逻辑处理。(由Redux负责)
Provider
react-redux提供了Provider组件,用于保存store给子组件中connect使用。
将它包裹在根组件的最外层,它会将store传递给容器组件。
Provider通过getChildContext方法将store保存到context里。
之后在connect会通过context读取store。
ReactDOM.render(
<Provider store={store}>
<ColorAppVisible/>
</Provider>,
document.getElementById("redux")
)
connect()
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
的作用是生成容器组件,容器组件将UI组件包装了起来,所有的数据都存放在容器组件上。
原理:
connect
接收mapStateToProps
、mapDispatchToProps
参数,生成一个wrapWithConnect
函数。- 该函数接收一个组件
WrappedComponent
作为参数。wrapWithConnect
函数中定义了一个Connect组件
。Connect组件
获取store中的mapStateToProps
和mapDispatchToProps
,生成新的属性dispatchProps
和stateProps
,并将它们和parentProps
合并在一起存储在nextState
中。
在Connect组件
的componentDidMount
中添加this.store.subscribe(this.handleChange)
订阅事件,实现页面交互。- 将
nextState
绑定到WrappedComponent
(即传入的组件)上。Connect组件
在componentWillUnmount
时移除订阅事件。
关键源码
export default function connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {}) {
return function wrapWithConnect(WrappedComponent) {
class Connect extends Component {
constructor(props, context) {
// 从祖先Component处获得store
this.store = props.store || context.store
this.stateProps = computeStateProps(this.store, props)
this.dispatchProps = computeDispatchProps(this.store, props)
this.state = { storeState: null }
// 对stateProps、dispatchProps、parentProps进行合并
this.updateState()
}
shouldComponentUpdate(nextProps, nextState) {
// 进行判断,当数据发生改变时,Component重新渲染
if (propsChanged || mapStateProducedChange || dispatchPropsChanged) {
this.updateState(nextProps)
return true
}
}
componentDidMount() {
// 改变Component的state
this.store.subscribe(() = {
this.setState({
storeState: this.store.getState()
})
})
}
render() {
// 生成包裹组件Connect
return (
<WrappedComponent {...this.nextState} />
)
}
}
Connect.contextTypes = {
store: storeShape
}
return Connect;
}
}
使用方式
const ColorAppVisible = connect(
mapStateToProps,
mapDispatchToProps
)(ColorApp);
mapStateToProps(state)
该方法的作用是:组件将监听store
的任何变化,返回需要传递给子组件的state
,返回的值将作为属性绑定在容器组件上。之后UI组件就可以通过this.props
去读取数据了。
export const mapStateToProps = (state) => {
return { colors: state.headerReducer }
}
mapDispatchToProps(dispatch)
该方法的作用是:将逻辑处理事件传递给子组件,返回一个dispatchProps
对象,该对象是action和dispatch的一个组合。返回的对象将被绑定在UI组件上,返回结果类似如下结构:
{
addItem: (text) => dispatch(action)
}
实际项目中可能会遇到很多个action,我们手动一个一个的添加太麻烦了,Redux提供了bindActionCreators
方法,作用是将Actions和dispatch组合起来,返回一个dispatchProps对象。
不使用bindActionCreators
时:
export const mapDispatchToProps = dispatch => ({
addAction:(colorText) => ({
type:ACTION_ADD,
color:{
id:guid(),
color:colorText
}
}),
updateAction:(color)=>({
type:ACTION_ADD,
color:color
})
})
使用bindActionCreators
时:
export const headerAction = {
addAction:(colorText) => ({
type:ACTION_ADD,
color:{
id:guid(),
color:colorText
}
}),
updateAction:(color)=>({
type:ACTION_ADD,
color:color
})
}
export const mapDispatchToProps = dispatch => ({
actions:bindActionCreators(headerAction,dispatch)
})
mergeProps()
[mergeProps(stateProps, dispatchProps, ownProps): props] (Function)
: 如果指定了这个参数,mapStateToProps()
与 mapDispatchToProps()
的执行结果和组件自身的 props 将传入到这个回调函数中。该回调函数返回的对象将作为 props 传递到被包装的组件中。你也许可以用这个回调函数,根据组件的 props 来筛选部分的 state 数据,或者把 props 中的某个特定变量与 action creator 绑定在一起。如果你省略这个参数,默认情况下返回 Object.assign({}, ownProps, stateProps, dispatchProps) 的结果。
options
[options] (Object)
如果指定这个参数,可以定制 connector 的行为。
[pure = true] (Boolean)
: 如果为 true,connector 将执行 shouldComponentUpdate
并且浅对比 mergeProps 的结果,避免不必要的更新,前提是当前组件是一个“纯”组件,它不依赖于任何的输入或 state 而只依赖于 props 和 Redux store 的 state。默认值为 true。
[withRef = false] (Boolean)
: 如果为 true,connector 会保存一个对被包装组件实例的引用,该引用通过 getWrappedInstance()
方法获得。默认值为 false
React-Redux流程图
流程简介:
component --> actionCreator(data) --> reducer --> component
react-redux
提供了Provider组件
和connect方法
Provider
接收store
作为props
,并通过context
传递给子组件。connect
接收到Provider
传出的store
后,经过一系列处理会将state
和actionCreator
传入组件的props
中,此时组件就可以调用actionCreator
来触发reducer
返回新的state
了,当connect
监听到state
变化了,就会调用setState
更新组件并将newState
传给组件。
响应流程:
- 当组件触发一个事件。
- 调用
actionCreator(data)
。 - 根据
actionCreator
调用对应的reducer
。 - 返回
newState
经过connect
处理传递给组件。
react-redux相较于单纯的redux,省略了dispatch、subscribe、getState这三步骤,这3个步骤均被connect函数实现了,Provider组件解决的是组件层级传参问题。