简介

react-redux 的 Provider 与 connect 实现学习笔记。

Provider

含义

Provider 是一个容器组件,它会把嵌套的内容原封不动作为自己的子组件渲染出来。

它还会把 Provider 的 store 属性存入 getChildContext 中,这样子组件可以通过 this.context.store 获取得到。

实现

export class Provider extends Component {
  static childContextTypes = {
    store: PropTypes.object
  }

  getChildContext () {
    return {
      store: this.props.store
    }
  }

  render () {
    return (
      <div>{this.props.children}</div>
    )
  }
}

Provider.propTypes = {
  store: PropTypes.object,
  children: PropTypes.any
};

connect

含义

高阶组件是一个函数,接收一个组件作为参数,对此组件做了一层拦截(有点像 es6 的装饰器、node 的中间件)。
作用是可以在此高阶组件内部对传进来来的组件做一些业务数据等前置处理。

connect 是一个函数,执行后返回一个高阶组件。接收两个参数 mapStateToProps 和 mapDispatchToProps 两个对象参数。
connect 函数的作用是可以使容器组件获取到 context 中的指定的值。

实现

export const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => {
  class Connect extends Component {
    constructor() {
      super();
      // == 用来保存需要传给被包装组件的所有的参数
      this.state = { allProps: {} };
    }

    static contextTypes = {
      store: PropTypes.object
    }

    // == 在 componentWillMount 生命周期即 subscribe 订阅函数。如果 store 变化即重新设置当前组件的 state
    componentWillMount() {
      const { store } = this.context;
      // == 调用 _updateProps 进行初始化
      this._updateProps();
      // == 通过 store.subscribe 监听数据变化重新调用 _updateProps
      // == 即所有使用到 connect 生成的组件都将接收新的 props 触发更新渲染
      store.subscribe(() => this._updateProps());
    }

    _updateProps() {
      const { store } = this.context;
      // == 这里的 store.getState() 才是实际参数
      let stateProps = mapStateToProps 
        ? mapStateToProps(store.getState(), this.props)
        : {};
      let dispatchProps = mapDispatchToProps
        ? mapDispatchToProps(store.dispatch, this.props)
        : {};
      this.setState({
        allProps: {
          ...stateProps,
          ...dispatchProps,
          ...this.props
        }
      });
    }

    render() {
      return <WrappedComponent {...this.state.allProps} />
    }
  }
}

源码阅读

地址: https://github.com/yunaichun/react-study

参考资料

powered by Gitbook该文件修订时间: 2023-05-16 18:08:03

results matching ""

    No results matching ""