React-Redux

                                             React-Redux 

 

1.  React-Redux 提供的一些公共组件及方法

(1)  Provider 组件

   这里引用简书里的一张图:

Provider 功能主要有如下两点:

1)  在原组件上包裹一层,使原来整个应用成为Provider的子组件

2)  接收Redux的store作为props, 通过context(上下文)对象传递给子孙组件上的connect

 核心代码很精简

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
}

  首先,对原组件进行了封装: render方法中,渲染了其子级元素,使整个应用成为Provider的子组件。

  (a) this.props.children 用于获取当前组件的所有子组件;

  (b) Children.only 用于获取仅有的一个子组件,没有或者超过一个匀会报错。所以注意:确保Provider组件的直接子级为单个封闭元素,切勿多个组件平行放置

   · 其次,传递store

   (a) constructor方法: Provider 初始化时,获取到props中的store对象;

   (b) getChildContext 方法:将外部的store对象放入context对象中,使子孙组件上的connect可以直接访问到context对象中的store.

   注: context可以使用子孙组件直接获取父级组件中的数据或方法,而无需一层一层通过props向下传递。 context对象相当于一个独立的空间,父组件通过getChildContext()向该空间内写值; 定义了contextTypes 验证的子孙组件可以通过this.context.xxx, 从context对象中读取xxx字段的值。

 

(2) connect 方法

1) connect 基本作用:

     a.  从context 里获取store

     b.  在componentWillMount 里通过mapStateToProps, mapDispatchToProps分别获取stateProp,dispatchProps的值

     c.  在componentWillMount 里订阅store的变化

     d.  将获得的stateProp, dispatchProps, 还有自生的props合成一个props传给下面组件

2) connect 是一个(高阶)函数,接收新状态及新属性方法及一个需要被包裹注入的组件。它会返回一个connect类,里面包着我们要渲染的wrappedComponent , 然后将stateProps,dispatchProps,还有ownProps合并起来,一起传给wrappedComponent(被重注入新props及操作行为的组件)

3)  connect可以接受四个参数: mapStatetToProps, mapDispatchToProps, mergeProps, options

4) connect 帮我们做了性能的优化,当state根props发生改变时,selector如果变化,最终计算出来的结果会进行一次浅比较来设置shouldComponentUpdate防止重复渲染。

5) connect 源码:

export const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => {
  class Connect extends Component {
    static contextTypes = {
      store: PropTypes.object
    }

    constructor () {
      super()
      this.state = {
        allProps: {}
      }
    }

    componentWillMount () {
      const { store } = this.context
      this._updateProps()
      store.subscribe(() => this._updateProps())
    }

    _updateProps () {
      const { store } = this.context
      let stateProps = mapStateToProps
        ? mapStateToProps(store.getState(), this.props)
        : {} // 防止 mapStateToProps 没有传入
      let dispatchProps = mapDispatchToProps
        ? mapDispatchToProps(store.dispatch, this.props)
        : {} // 防止 mapDispatchToProps 没有传入
      this.setState({
        allProps: {
          ...stateProps,
          ...dispatchProps,
          ...this.props
        }
      })
    }

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

 

 

未完待续.....

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值