React Redux 原始碼解析

2021-09-12 01:20:30 字數 3837 閱讀 7770

一般而言,我檢視乙個庫的源**,首先回檢視對應方法的引數,其次是對應的return,然後再看**的具體實現。

通過檢視原始碼,發現createstore方法返回了乙個物件, 該物件共暴露出了五個方法,四個常用的方法:

return 

複製**複製**

檢視原始碼的開始部分,我們發現createstore可以傳入兩個三個引數:

export default function createstore(reducer, preloadedstate, enhancer) 

複製**複製**

其中第乙個引數reducer是必須要傳遞的而且必須是乙個函式,不然redux回報一場

if (typeof reducer !== 'function') 

複製**複製**

如果傳遞了第二個引數preloadedstate,而且第二個引數不是乙個function, 則將preloadedstate儲存在內部變數currentstate中, 也就是我們給state的預設狀態

如果preloadedstate是乙個function , 則將preloadedstate 賦值給enhancer

if (typeof preloadedstate === 'function' && typeof enhancer === 'undefined') 

if (typeof enhancer !== 'undefined')

// 執行enhancer, 一般enhancer 就是一組中介軟體

return enhancer(createstore)(reducer, preloadedstate)

} if (typeof reducer !== 'function')

複製**複製**

該方法中儲存了三個重要的變數:

let currentreducer = reducer

let currentstate = preloadedstate

let currentlisteners =

複製**複製**

currentreducer 儲存了所有的reducer

currentstate 將狀態資料都儲存在這裡,也是redux 運算元據的唯一物件

currentlisteners 會儲存對redux state 訂閱的監聽者

我們已經知道了redux能控制的如上三個主要內部變數了, 接下拉我們會 根據createstore暴露出來的五個方法,來學習怎麼去操作這三個變數

return 

複製**複製**

function dispatch(action)  finally 

// 對訂閱者進行處理

const listeners = (currentlisteners = nextlisteners)

for (let i = 0; i < listeners.length; i++)

return action

}複製**複製**

首先需要傳遞乙個action引數來告訴需要做的操作物件,action 只能是乙個object, 而且必須包含type字段

if (!isplainobject(action)) 

if (typeof action.type === 'undefined')

複製**複製**

我們會呼叫內部變數currentreducer去處理發起的對應的action

currentstate = currentreducer(currentstate, action)

複製**複製**

我們會發現currentreducer其實是乙個function, 而且需要兩個引數:currentstate,action.

currentreducer返回的值賦值給currentstate, 由createstore傳入引數的分析得知,preloadedstate只能是要給object, 所以currentreducerfunction 返回的是要給object.

從這一行**我們可以總結得到:

reducer 其實就是乙個函式,根據action 對 currentstate 進行處理,並且返回新的currentstate 的函式

const listeners = (currentlisteners = nextlisteners)

for (let i = 0; i < listeners.length; i++)

複製**複製**

由上面一段**我們可以得知,在更新state, 需要去遍歷執行所有的監聽者(listener),讓監聽者得知state變更的資訊

subscribe顧名思義就是訊息訂閱的意思

function subscribe(listener)    

issubscribed = false

ensurecanmutatenextlisteners()

const index = nextlisteners.indexof(listener)

nextlisteners.splice(index, 1)

}}複製**複製**

很簡單的一段**, 傳入的引數listener 就是乙個訂閱者方法,

nextlisteners.push(listener)

複製**複製**

將listener 儲存在內部變數陣列中。返回乙個unsubscribe方法, 用來取消訂閱

nextlisteners.splice(index, 1) // 只要從陣列中刪除listener 就是取消訂閱了

複製**複製**

function

getstate

() 複製**複製**

非常簡單,就是返回內部變數currentstate

function replacereducer(nextreducer) )

}複製**複製**

就是替換當前的reducer.

首先我們需要呼叫createstore方法建立乙個store

let store = createstore(reducer, preloadedstate)

複製**複製**

reducer 是乙個function, 而且必須要 傳遞兩個引數,第乙個是state, 第二個是乙個action

利用相關事件觸發store.dispatch(action)去變更狀態

這個action 必須要有type屬性

訂閱狀態變更store.subscribe(listener)

在listener中去獲取最新state(store.getstate()),然後做去相應的處理

可以在

react redux原始碼解析

react redux原始碼 1.provider 把基於屬性傳遞進來的store掛載到上下文上 2.connect provider建立乙個元件 並把store掛載到上下文中供後代使用 connect 第乙個執行返回是乙個函式 第二個執行返回是乙個元件 元件 proxy 渲染proxy目的是把傳進...

react redux 原始碼學習

function createstate reducer dispatch 然後將 我們要用到的 getstate,dispatch,subscribe 給暴露出去 return 這裡是使用了 react 的 上下文內容,不贅述 export class provide extends compon...

原始碼解讀 react redux

toc 其中高階元件如果你不太了解也無所謂,你只需要知道,高階元件就是乙個工廠函式,它接收乙個元件類 或者函式元件 返回乙個被修改後的新的元件類。connect就是乙個高階元件。文章內會使用的簡寫 我們知道,react redux 為開發者提供了 redux 到 react 的 binding。本文...