react-redux中的數(shù)據(jù)傳遞

1、connect

connect用于連接React組件與 Redux store,其使用方法如下

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

[mapStateToProps(state, [ownProps]): stateProps]是connect的第一個(gè)參數(shù),其類型為function,允許我們將 store 中的數(shù)據(jù)作為 props 綁定到組件上。

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

(1)這個(gè)函數(shù)的第一個(gè)參數(shù)就是 Redux 的 store,我們不必將 store中的數(shù)據(jù)原封不動(dòng)地傳入組件,可以根據(jù) state 中的數(shù)據(jù),動(dòng)態(tài)地輸出組件需要的(最?。傩浴?/p>

(2)函數(shù)的第二個(gè)參數(shù) ownProps,是組件自己的 props。有的時(shí)候,ownProps 也會(huì)對(duì)其產(chǎn)生影響。

當(dāng) state 變化,或者 ownProps 變化的時(shí)候,mapStateToProps 都會(huì)被調(diào)用,計(jì)算出一個(gè)新的 stateProps,(在與 ownProps merge 后)更新給組件。

[mapDispatchToProps(dispatch, ownProps): dispatchProps]將 action 作為 props 綁定到組件上,也會(huì)成為 MyComp 的 props。

stateProps 和 dispatchProps,都需要和 ownProps merge 之后才會(huì)被賦給組件。connect 的第三個(gè)參數(shù)就是用來做這件事。如果不傳這個(gè)參數(shù),connect 就會(huì)使用 Object.assign替代該方法。

connect 的第四個(gè)參數(shù)[options] (Object) 如果指定這個(gè)參數(shù),可以定制 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 }
        // 對(duì)stateProps、dispatchProps、parentProps進(jìn)行合并
        this.updateState()
      }
      shouldComponentUpdate(nextProps, nextState) {
        // 進(jìn)行判斷,當(dāng)數(shù)據(jù)發(fā)生改變時(shí),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是一個(gè)高階函數(shù)
首先,傳入mapStateToProps、mapDispatchToProps
然后,返回一個(gè)生產(chǎn)Component的函數(shù)(wrapWithConnect)
最后,將真正的Component作為參數(shù)傳入wrapWithConnect
這樣就生產(chǎn)出一個(gè)經(jīng)過包裹的Connect組件,該組件具有如下特點(diǎn):

通過props.store獲取祖先Component的storeprops包括stateProps、dispatchProps、parentProps,合并在一起得到nextState,作為props傳給真正的Component
componentDidMount時(shí),添加事件this.store.subscribe(this.handleChange),實(shí)現(xiàn)頁(yè)面交互
shouldComponentUpdate時(shí)判斷是否有避免進(jìn)行渲染,提升頁(yè)面性能,并得到nextState
componentWillUnmount時(shí)移除注冊(cè)的事件this.handleChange

2、Provider

Provider組件主要有以下兩個(gè)作用:

1、在原應(yīng)用組件上包裹一層,使原來整個(gè)應(yīng)用成為Provider的子組件
2、接收Redux的store作為props,通過context對(duì)象傳遞給子孫組件

其代碼如下

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獲得數(shù)據(jù),實(shí)現(xiàn)過程如下,可以看到在沒有定義props的情況下,通過context直接取得store中的數(shù)據(jù)。

...
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()
}
...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 做React需要會(huì)什么? react的功能其實(shí)很單一,主要負(fù)責(zé)渲染的功能,現(xiàn)有的框架,比如angular是一個(gè)大而...
    蒼都閱讀 14,949評(píng)論 1 139
  • 前言 本文 有配套視頻,可以酌情觀看。 文中內(nèi)容因各人理解不同,可能會(huì)有所偏差,歡迎朋友們聯(lián)系我討論。 文中所有內(nèi)...
    珍此良辰閱讀 12,169評(píng)論 23 111
  • 我們已經(jīng)詳細(xì)介紹了Action,Reducer,Store和它們之間的流轉(zhuǎn)關(guān)系。Redux的基礎(chǔ)知識(shí)差不多也介紹完...
    張歆琳閱讀 3,875評(píng)論 1 17
  • 今天來看一下react組件之間是怎么進(jìn)行通訊的。react推崇的是單向數(shù)據(jù)流,自上而下進(jìn)行數(shù)據(jù)的傳遞,但是由下而上...
    親親qin閱讀 6,075評(píng)論 2 12
  • 學(xué)習(xí)必備要點(diǎn): 首先弄明白,Redux在使用React開發(fā)應(yīng)用時(shí),起到什么作用——狀態(tài)集中管理 弄清楚Redux是...
    賀賀v5閱讀 9,066評(píng)論 10 58

友情鏈接更多精彩內(nèi)容