React-Redux是在Redux的基础上,将其大量重复的代码进行了封装。
1. Provider
利用context对象给所有子组件提供store。不再需要在每个组件都引用store。
import React, { Component } from ‘react‘; import Context from ‘./context‘; // 给connect等方法提供store export default class Provider extends Component { render() { return ( <Context.Provider value={{store: this.props.store}}> {this.props.children} </Context.Provider> ) } }
2. connect
该方法封装了大量的逻辑,主要如下:
1. 给使用connect方法的组件属性自动绑定了dispatch方法;this.props.dispatch 2. 给使用connect方法的组件的setState方法自动添加了对仓库的state的订阅 3. 给使用connect方法的组件的属性绑定仓库的state值;this.props.XXXX 不再使用store.getState方法 4. 给使用connect方法的组件的actions自动使用bindActionCreators方法
import React, { Component } from ‘react‘; import Context from ‘./context‘; import { bindActionCreators } from ‘redux‘; /** * * @param {function} mapStateToProps 绑定state到组件的props * @param {funtion|object} mapDispatchToProps 返回actions对象 */ export default function(mapStateToProps, mapDispatchToProps) { return function(WrappedComponent) { return class extends Component { static contextType = Context; constructor(props, context) { super(props); // 被映射的state, 即mapStateToProps的返回值, 绑定到组件的props上 this.state = mapStateToProps(context.store.getState()); } componentDidMount() { this.unsubscribe = this.context.store.subscribe(() => { // setState的用法;传一个state对象 this.setState(mapStateToProps(this.context.store.getState())); }) } componentWillUnmount() { this.unsubscribe(); } render() { const { dispatch } = this.context.store; let actions = {}; if (typeof mapDispatchToProps === ‘object‘){ actions = mapDispatchToProps; } if (typeof mapDispatchToProps === ‘function‘) { actions = mapDispatchToProps(dispatch); } const bindActions = bindActionCreators(actions, dispatch) return ( <WrappedComponent dispatch={dispatch} {...this.state} {...bindActions} /> ) } } } }