美文网首页
react-redux中的数据传递

react-redux中的数据传递

作者: cfighter | 来源:发表于2017-08-02 15:40 被阅读0次

    1、connect

    connect用于连接React组件与 Redux store,其使用方法如下

    connect([mapStateToProps], [mapDispatchToProps], [mergeProps],[options])
    

    [mapStateToProps(state, [ownProps]): stateProps]是connect的第一个参数,其类型为function,允许我们将 store 中的数据作为 props 绑定到组件上。

    const mapStateToProps = (store) => {
      return {
        count:store.count
      }
    }
    

    (1)这个函数的第一个参数就是 Redux 的 store,我们不必将 store中的数据原封不动地传入组件,可以根据 state 中的数据,动态地输出组件需要的(最小)属性。

    (2)函数的第二个参数 ownProps,是组件自己的 props。有的时候,ownProps 也会对其产生影响。

    当 state 变化,或者 ownProps 变化的时候,mapStateToProps 都会被调用,计算出一个新的 stateProps,(在与 ownProps merge 后)更新给组件。

    [mapDispatchToProps(dispatch, ownProps): dispatchProps]将 action 作为 props 绑定到组件上,也会成为 MyComp 的 props。

    stateProps 和 dispatchProps,都需要和 ownProps merge 之后才会被赋给组件。connect 的第三个参数就是用来做这件事。如果不传这个参数,connect 就会使用 Object.assign替代该方法。

    connect 的第四个参数[options] (Object) 如果指定这个参数,可以定制 connector 的行为,一般不用。

    connect核心代码:

    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;
        }
      }
    

    可以看到connect是一个高阶函数
    首先,传入mapStateToProps、mapDispatchToProps
    然后,返回一个生产Component的函数(wrapWithConnect)
    最后,将真正的Component作为参数传入wrapWithConnect
    这样就生产出一个经过包裹的Connect组件,该组件具有如下特点:

    通过props.store获取祖先Component的storeprops包括stateProps、dispatchProps、parentProps,合并在一起得到nextState,作为props传给真正的Component
    componentDidMount时,添加事件this.store.subscribe(this.handleChange),实现页面交互
    shouldComponentUpdate时判断是否有避免进行渲染,提升页面性能,并得到nextState
    componentWillUnmount时移除注册的事件this.handleChange

    2、Provider

    Provider组件主要有以下两个作用:

    1、在原应用组件上包裹一层,使原来整个应用成为Provider的子组件
    2、接收Redux的store作为props,通过context对象传递给子孙组件

    其代码如下

    export default class Provider extends Component {
      getChildContext() {
        return { store: this.store }
      }
    
      constructor(props, context) {
        super(props, context)
        this.store = props.store
      }
    
      render() {
        return Children.only(this.props.children)
      }
    }
    
    if (process.env.NODE_ENV !== 'production') {
      Provider.prototype.componentWillReceiveProps = function (nextProps) {
        const { store } = this
        const { store: nextStore } = nextProps
    
        if (store !== nextStore) {
          warnAboutReceivingStore()
        }
      }
    }
    
    Provider.propTypes = {
      store: storeShape.isRequired,
      children: PropTypes.element.isRequired
    }
    Provider.childContextTypes = {
      store: storeShape.isRequired
    }
    

    从上面的代码可以看出Provider是通过context传递给子组件的,子组件通过connect获得数据,实现过程如下,可以看到在没有定义props的情况下,通过context直接取得store中的数据。

    ...
    constructor(props, context) {
            this.store = props.store || context.store 
            this.stateProps = computeStateProps(this.store, props)
            this.dispatchProps = computeDispatchProps(this.store, props)
            this.state = { storeState: null }
            this.updateState()
    }
    ...
    

    相关文章

      网友评论

          本文标题:react-redux中的数据传递

          本文链接:https://www.haomeiwen.com/subject/txuklxtx.html