react-redux 提供了 connect 和 provider 两个好方式,provider 将组件和 redux 关联起来,将 store 传给组件,组件通过 dispatch 发出 action,store 根据 action 的 type 属性,调用对应的 reducer 并传入 state 和这个 action,reducer 对 state 进行处理并返回一个新的 state 放入 store,connect 监听 store 发生变化,调用 setState 更新组件,此时组件的 props 也就跟着发生变化
connect,Provider,mapStateToProps,mapDispatchToProps, 是 react-redux 提供的,redux 本身和 react 没有关系,它只是数据处理中心,是 react-redux 让它们联系在一起。redux 由 store,reducer,action 组成
store 是一个对象,它主要有四个方法
dispatch:用于 action 的分发,在 creactStore 中对 dispatch 进行改造,比如当 action 传入 dispatch 中会立即触发 reducer,有时我们不希望立即触发,而是等待异步操作结束后触发,这时不是只能传入一个对象,而是能传入一个函数,在函数里我们 dispatch 一个 action 对象,实现了异步
subscribe:监听 state 的变化,这个函数调用 dispatch 时会注册一个 listener 监听 state 变化当我们需要知道 state 是否变化时可以调用,它返回一个函数,调用这个返回的函数可以注销监听,let unsubscribe=store.subscribe(()=>{console.log(“state 发生了变化 ”)})
getState:
两个需要用到的地方:
1. 获取 store 中的 state,用 action 触发 reducer 改变了 state 时,并将数据传给 reducer 这个过程是自动执行的
2. 利用 subscribe 监听到 state 发生变化后调用它来获取新的 state 数据
replaceReducer:
替换 reducer,改变 state 修改的逻辑
store 通过 createStore() 方法创建,接受三个参数,经过 combineReducers 合并的 reducer 和 state 初始状态以及改变 dispatch 的中间件,后两个参数不是必须的,store 的主要作用是将 action 和 reducer 联系起来并改变 state,
action
action 是一个对象,其中 type 属性是必须的,同时可以传入一些数据,action 可以用 actionCreator 进行创造,dispatch 就是把 action 对象发送出去
reducer
reducer 是一个函数,它接受一个 state 和一个 action,根据 action 的 type 返回一个新的 state 根据业务逻辑可以分为多个 reducer,然后通过 combineReducers 将它们合并,state 中有很多对象,每个 state 对象对应一个 reducer,
eg:
const reducer =combineReducers(
{
a:doSomethingWithA,
b:processB,
c:c
}
)
combineReducers:
其实它也是一个 reducer,它接受整个 state 和一个 action,然后将整个 state 拆分发送给对应的 reducer 进行处理,所有的 reducer 会收到相同的 action,不过他们会根据 action 的 type 进行判断,有这个就进行处理然后返回新的 state,没有就返回默认值,然后分散的 state 又会整合在一起返回一个新的 state,
connect
connect(mapStateToProps,mapDispatchToProps,mergeProps,options)是一个函数,它接受
四个参数并且再返回一个函数,wrapWithConnect,wrapWithConnect 接受一个组件作为参数,它的内部定义一个新组件,并将传入的组件作为 Connect 的子组件然后 return 回去。
完整写法:
connect(mapStateToProps,mapDispatchToProps,mergeProps,options)(component)
mapStateToProps(state,[ownProps])
1.mapStateToProps 接受两个参数,store 的 state 和自定义的 props,
2. 并返回一个新的对象,这个对象会作为 props 的一部分传入 ui 组件,
3. 我们可以根据组件所需要的数据自定义返回一个对象,ownProps 的变化也会触发 mapStateProps
function mapStateToProps(state){
return {todos:state.todos};
}
mapDispatchToProps(dispatch,[ownProps])
1.mapDispatchToProps 如果是对象,那么会和 store 绑定作为 props 的一部分传入 ui 组件
2. 如果是个函数,它接受两个参数,bindActionCreators 会将 action 和 dispatch 绑定并返回一个对象,这个对象会和 ownProps 一起作为 props 的一部分传入 ui 组件,
3. 所以不论 mapDispatchToProps 是对象还是函数,它最终都会返回一个对象,如果是函数,这个对象的 key 值是可以自定义的。
4.mapDispatchToProps 返回的对象属性其实就是一个个 actionCeator,因为已经和 dispatch 绑定,所以当调用 actionCreator 时会立即发送 action,而不是手动 dispatch,
5.ownProps 的变化也会触发 mapDispatchToProps
mergeProps(tateProps,dispatchProps,ownProps)
将 mapStateToProps() 和 mapDispatchToProps() 返回的对象和组件自身的 props 合并成新的 props 并传入组件,默认返回 stateProps 和 dispatchProps 的结果之和
options:
pure=true 表示 Connect 容器组件将在 shouldComponentUpdate 中对 store 的 state 和 ownProps 进行浅对比,判断是否发生变化,优化性能,为 false 则不对比。
完整的 React–Redux–React 流程
一.Provider 组件接受 redux 的 store 作为 props,然后通过 context 往下传
二.connect 函数在初始化的时候会将 mapDispatchToProps 对象绑定到 store,
如果 mapDispatchToProps 是函数则在 Connect 组件获得 store 之后,根据传入的 store.dispatch 和 action 通过 bindActionCreators 进行绑定,再将返回的对象绑定到 store,connect 函数会返回一个 wrapWithConnect 函数,同时 wrapWithConnect 会被调用且传入一个 ui 组件,wrapWithConnect 内部定义了一个 Connect 组件,传入的 ui 组件是 Connect 的子组件,
然后 Connect 组件会通过 context 获得 store,并通过 store.getState 获得完整的 state 对象,将 state 传入 mapStateToProps 返回 stateProps 对象,
然后 Connect 组件会通过 context 获得 store,并通过 store.getState 获得完整的 state 对象,将 state 传入 mapStateToProps 返回 stateProps 对象、mapDispatchToProps 对象或 mapDispatchToProps 函数会返回一个 dispatchProps 对象,stateProps、dispatchProps 以及 Connect 组件的 props
三. 此时 ui 组件就可以在 props 中找到 actionCreator,
当我们调用 actionCreator 时会自动调用 dispatch,
在 dispatch 中会调用 getState 获取整个 state,同时注册一个 listener 监听 state 的变化,store 将获得的 state 和 action 传给 combineReducers,
combineReducers 会将 state 依据 state 的 key 值分别传给子 reducer,并将 action 传给全部子 reducer,
reducer 会被依次执行进行 action.type 的判断,如果有则返回一个新的 state,如果没有则返回默认。
combineReducers 再次将子 reducer 返回的单个 state 进行合并成一个新的完整的 state。此时 state 发生了变化。
dispatch 在 state 返回新的值之后会调用所有注册的 listener 函数其中包括 handleChange 函数,
handleChange 函数内部首先调用 getState 获取新的 state 值并对新旧两个 state 进行浅对比,如果相同直接 return,
如果不同则调用 mapStateToProps 获取 stateProps 并将新旧两个 stateProps 进行浅对比,如果相同,直接 return 结束,不进行后续操作。如果不相同则调用 this.setState() 触发 Connect 组件的更新,传入 ui 组件,触发 ui 组件的更新,此时 ui 组件获得新的 props,
react –> redux –> react 的一次流程结束。