亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

[源碼解讀] react-redux

Olivia / 3148人閱讀

摘要:本文并不逐行地對源碼進行細致分析,不如說是基于以下幾個問題,對源碼進行大致的掃覽。我們已經(jīng)知道,中,允許用戶注冊監(jiān)聽器,這些監(jiān)聽器會在每次執(zhí)行結(jié)束后遍歷觸發(fā)。省略一些無關(guān)代碼其中,是為了在嵌套的中嵌套執(zhí)行。

react-redux 源碼解讀

[TOC]

前置知識

閱讀本篇文章前,請先確認(rèn)你是否了解以下知識:

react

redux

高階組件

react diff 機制

其中高階組件如果你不太了解也無所謂,你只需要知道,高階組件就是一個工廠函數(shù),它接收一個組件類(或者函數(shù)組件),返回一個被修改后的新的組件類。connect 就是一個高階組件。

文章內(nèi)會使用的簡寫

hoc: 高階組件(higher order component)

scu: shouldComponentUpdate

Issues

我們知道,react-redux 為開發(fā)者提供了 redux 到 react 的 binding。本文并不逐行地對源碼進行細致分析,不如說是基于以下幾個問題,對源碼進行大致的掃覽。

我們把關(guān)注點放在:

connect 是通過什么方式來連接 store 的?

怎么分發(fā) state tree 到子組件的?
provider 僅僅只是保持了一個 store 實例,即使 store 中的 state tree 變化了,由于 react diff 階段只做淺比較,僅比較對象引用,故 provider.props.store 被視為未發(fā)生變化,那就無法把新的 state tree 分發(fā)到子組件了。

我們知道 connect 還接收若干配置函數(shù),用來 mapXxToProps ,以及設(shè)置是否進行 pure 優(yōu)化等。這些沒什么意思,我們就不 care 了。

兩個核心 api

react-redux 只有兩個核心的部分

Provider

connect

Provider

Provider 的作用僅僅是維護一個 store 實例,并使用 context , 為分發(fā) state tree 提供了機制

connect

connect 顧名思義,連接 container 和 store ,使得 container 能響應(yīng) state tree 的變化。

connect 本身是一個高階組件,它調(diào)用了 connectAdvanced 這么一個工廠函數(shù)。

而上面提到的兩個問題,全都由 connectAdvanced 封裝了。

connectAdvanced

connectAdvanced 是一個高階組件的工廠函數(shù),它返回一個 hoc (高階組件),這個 hoc 最終返回一個 Connect(WrappedComponent) 的組件。

connect 是通過什么方式來連接 store 的?

在這個 Connect(WrappedComponent) 中,聲明了 getChildContext 函數(shù),通過它來獲取到 Provider 中共享的 store 實例。

NOTE : 理論上,Provider 下任何一個子組件,只要我們也去聲明了 getChildContext ,那么它就和 connect 了一樣,可以得到 store 實例了。

connect 怎么分發(fā) state tree 到子組件的?

一句話,主要通過 store.subscribe 接口和組件 props 變更自動 re-render 機制。

在 react-redux 中,我們定義了這么幾個東西,幫助我們來做到上面幾件事情。

selector

subscriptions

每個 Connect(WrappedComponent) 在構(gòu)造函數(shù)中都需要 init 上述兩個實體。

selector

selector 主要由 selectorFactory 構(gòu)造,selector 內(nèi)部包含

一個計算新 props 的生成函數(shù)
sourceSelector(store.getState(), props)
其中 props 是 selector 之前緩存的,后續(xù)會直接拿來和 store.getState() 比較引用

一個 shouldComponentUpdate 的標(biāo)識
Connect(WrappedComponent) 內(nèi)部是直接使用它來判斷 scu 的

shouldComponentUpdate() {
  return this.selector.shouldComponentUpdate
}    

源碼如下

const selector = {
    // 實際 run 的邏輯又是在 SelectorFactory 里定義的,這里只是做 scu
    run: function runComponentSelector(props) {
      try {
        const nextProps = sourceSelector(store.getState(), props)
        // connect 的 scu 實際邏輯在這里定義了
        // 比較 run 之后兩次 props 的引用是否仍然保持相等
        if (nextProps !== selector.props || selector.error) {
          selector.shouldComponentUpdate = true
          selector.props = nextProps
          selector.error = null
        }
      } catch (error) {
        selector.shouldComponentUpdate = true
        selector.error = error
      }
    }
  }

調(diào)用 selector.run 的時候,主要做了兩件事情

根據(jù)之前緩存的 prevProps 和當(dāng)前 redux store 實例中的 statet tree 生成新的 props。

通過比較引用,更新 shouldComponentUpdate 判斷標(biāo)識

Connect(WrappedComponent) 會在三處調(diào)用 selector.run

componentDidMount

componentWillReceiveProps

onStateChanged

之后 React 就會自動向子組件分發(fā)變更后的 props ,實現(xiàn) re-render。

subcription

我們在上面提到過 Provider 本身是無法通知 state tree 的變化的,于是為了監(jiān)聽 state tree 變化,我們需要通過 store.subcribe 接口,來向 Provider 的 store 實例注冊一些監(jiān)聽器。

我們已經(jīng)知道,redux 中,store.subcribe 允許用戶注冊監(jiān)聽器,這些監(jiān)聽器會在每次 dispatch 執(zhí)行結(jié)束后遍歷觸發(fā)。

于是在 react-redux 中, Connect(WrappedComponent) 中的 subcription 最終就是被注冊到 store 中。

initSubscription() {
    // ...省略一些無關(guān)代碼
    this.subscription = new Subscription(this.store, parentSub, this.onStateChange.bind(this))
}

其中,

parentSub 是為了在嵌套的 connect 中嵌套執(zhí)行 subscription。

new Subscription 主要構(gòu)造了一個包含 trySubscribe 方法的對象

trySubscribe() {
    if (!this.unsubscribe) {
      this.unsubscribe = this.parentSub
        ? this.parentSub.addNestedSub(this.onStateChange)
        : this.store.subscribe(this.onStateChange)

      this.listeners = createListenerCollection()
    }
  }

Connect(WrappedComponent)componentDidMounttrySubscribe,在 componentWillUnmounttryUnsubscribe

而 trySubscribe 的主要邏輯就是將 onStateChange 注冊到 redux.store 中。

而我們已經(jīng)說過,onStateChange 主要就是執(zhí)行 selector.run

onStateChange() {
  // 得到新的 props 和 state
  this.selector.run(this.props)

  if (!this.selector.shouldComponentUpdate) {
    this.notifyNestedSubs()
  } else {
    this.componentDidUpdate = this.notifyNestedSubsOnComponentDidUpdate
    this.setState(dummyState)
  }
}

于是,每次 state tree 發(fā)生變化后,或者更準(zhǔn)確地說,每次 dispatch 成功后,redux.store 都會通過注冊好的 subscription,執(zhí)行 Connect(WrappedComponent) 中的 onStateChange ,再由 selector.run 來判斷是否需要生成新的 props。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/87218.html

相關(guān)文章

  • react-redux用法及源碼解讀

    摘要:帶有內(nèi)部狀態(tài),內(nèi)部可以使用。代表監(jiān)聽的全局,也可以說是全局的,表示該組件自身攜帶的方法。回答問題是通過應(yīng)用的,將通過頂層組件傳遞到上下文環(huán)境中。所有頁面集合緩存不用每次都重新加載通過綁定用法完參考文章 react-redux把組件分為UI組件和容器組件。先看圖下圖: showImg(https://segmentfault.com/img/bVbkVBz?w=1378&h=1194);...

    Zoom 評論0 收藏0
  • dva系列源碼解讀

    摘要:介紹概述本次對源碼的解讀除了傳統(tǒng)的從入手外還將引入帶入問題讀源碼的理念,因為只有這樣當(dāng)讀完源碼之后才會有切身的收獲。 介紹 概述 本次對 dva 源碼的解讀除了傳統(tǒng)的從 api 入手外還將引入帶入問題讀源碼的理念,因為只有這樣當(dāng)讀完源碼之后才會有切身的收獲。另外除了 dva 的源碼外還會解讀一些常用的 dva 插件的源碼。 電子書 https://dva-source-docs.net...

    focusj 評論0 收藏0
  • Redux系列源碼解讀

    摘要:源碼解讀的方法就是給我們提供了靈活的創(chuàng)建符合標(biāo)準(zhǔn)的的方法。用于分解樹,每一個對應(yīng)的一個對應(yīng)的子。這樣在將傳遞給時利于分解。源碼實現(xiàn)了這種將函數(shù)數(shù)組,通過的方法,實現(xiàn)層層嵌套的執(zhí)行,達到中間件的實現(xiàn)。 Redux 源碼解讀 1.redux-action createAction redux-action的createAction方法就是給我們提供了靈活的創(chuàng)建符合FSA標(biāo)準(zhǔn)的actio...

    Scliang 評論0 收藏0
  • 帶著問題看 react-redux 源碼實現(xiàn)

    摘要:更新類型及具體內(nèi)容負(fù)責(zé)更新數(shù)據(jù)的具體邏輯。即根據(jù)當(dāng)前及攜帶的信息合成新的數(shù)據(jù)。下面帶著這些問題深入了解本質(zhì)上也是高階組件的一種實現(xiàn)。核心實現(xiàn)聲明以被子組件獲取。通過的實現(xiàn),我們可以得到的重要性淺比較的實現(xiàn)由此可以看到的重要性。前言 Redux作為通用的狀態(tài)管理器,可以搭配任意界面框架。所以并搭配react使用的話就要借助redux官方提供的React綁定庫react-redux,以高效靈活的...

    JellyBool 評論0 收藏0
  • 重讀redux源碼(二)

    摘要:函數(shù)組合,科里化的串聯(lián)結(jié)合示例源碼,實現(xiàn)也很優(yōu)雅,對于返回的,將等參數(shù)傳遞進去,然后執(zhí)行,等待回調(diào)異步完成再。對于正常對象則進行下一步。前言 作為前端狀態(tài)管理器,這個比較跨時代的工具庫redux有很多實現(xiàn)和思想值得我們思考。在深入源碼之前,我們可以相關(guān)注下一些常見問題,這樣帶著問題去看實現(xiàn),也能更加清晰的了解。 常見問題 大概看了下主要有這么幾個: redux三大原則 這個可以直接參考...

    dingda 評論0 收藏0

發(fā)表評論

0條評論

Olivia

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<