Redux源碼解讀

今天向大家簡單介紹下Redux源碼,若有理解差誤,歡迎在下面留言~

Redux源碼地址:https://github.com/reactjs/redux/tree/master/src

大家可以看到Redux目錄結(jié)構(gòu)為

redux.png

我們只介紹最重要的一個文件夾createStore.js


import isPlainObject from 'lodash/isPlainObject'
import $$observable from 'symbol-observable'


export const ActionTypes = {

INIT: '@@redux/INIT'   //這就是當你在創(chuàng)建一個store時,最開始的action.type值

}

/*
參數(shù)reducer就是你傳入的要更改state的函數(shù)
參數(shù)preloadedState是可選參數(shù)知给,指初始state
參數(shù)enhancer也是可選,一般不用
*/
export default function createStore(reducer, preloadedState, enhancer) {

if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {

enhancer = preloadedState

preloadedState = undefined

}

if (typeof enhancer !== 'undefined') {

if (typeof enhancer !== 'function') {

throw new Error('Expected the enhancer to be a function.')

}

return enhancer(createStore)(reducer, preloadedState)

}

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

throw new Error('Expected the reducer to be a function.')

}

let currentReducer = reducer

let currentState = preloadedState

let currentListeners = []

let nextListeners = currentListeners

let isDispatching = false

function ensureCanMutateNextListeners() {

if (nextListeners === currentListeners) {

nextListeners = currentListeners.slice()

}

}

//得到當前的state值
function getState() {

return currentState

}

/*
參數(shù)listener是一個監(jiān)聽函數(shù)
返回值為一個取消監(jiān)聽的函數(shù)
*/
function subscribe(listener) {

if (typeof listener !== 'function') {

throw new Error('Expected listener to be a function.')

}

let isSubscribed = true

ensureCanMutateNextListeners()

nextListeners.push(listener) // 添加在監(jiān)聽數(shù)組中

return function unsubscribe() {

if (!isSubscribed) {

return

}

isSubscribed = false

ensureCanMutateNextListeners()

const index = nextListeners.indexOf(listener)

nextListeners.splice(index, 1)

}

}

/*
參數(shù)action為你傳入的用戶進行的操作對象
*/
function dispatch(action) {

if (!isPlainObject(action)) {

throw new Error(

'Actions must be plain objects. ' +

'Use custom middleware for async actions.'

)

}

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

throw new Error(

'Actions may not have an undefined "type" property. ' +

'Have you misspelled a constant?'

)

}

if (isDispatching) {

throw new Error('Reducers may not dispatch actions.')

}

try {

isDispatching = true

//現(xiàn)在的currentReducer就是你傳入的reducer,執(zhí)行這個函數(shù)對state進行更新砚偶,返回給當前的currentState。
currentState = currentReducer(currentState, action)

} finally {

isDispatching = false

}
//遍歷出當前所有的監(jiān)聽洒闸,并依次執(zhí)行染坯。
const listeners = currentListeners = nextListeners

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

const listener = listeners[i]

listener()

}

return action

}

/**

 * Replaces the reducer currently used by the store to calculate the state.

 *

 * You might need this if your app implements code splitting and you want to

 * load some of the reducers dynamically. You might also need this if you

 * implement a hot reloading mechanism for Redux.

 *

 * @param {Function} nextReducer The reducer for the store to use instead.

 * @returns {void}

 */

function replaceReducer(nextReducer) {

if (typeof nextReducer !== 'function') {

throw new Error('Expected the nextReducer to be a function.')

}

currentReducer = nextReducer

dispatch({ type: ActionTypes.INIT })

}

/**

 * Interoperability point for observable/reactive libraries.

 * @returns {observable} A minimal observable of state changes.

 * For more information, see the observable proposal:

 * https://github.com/zenparsing/es-observable

 */

function observable() {

const outerSubscribe = subscribe

return {

/**

 * The minimal observable subscription method.

 * @param {Object} observer Any object that can be used as an observer.

 * The observer object should have a `next` method.

 * @returns {subscription} An object with an `unsubscribe` method that can

 * be used to unsubscribe the observable from the store, and prevent further

 * emission of values from the observable.

 */

subscribe(observer) {

if (typeof observer !== 'object') {

throw new TypeError('Expected the observer to be an object.')

}

function observeState() {

if (observer.next) {

observer.next(getState())

}

}

observeState()

const unsubscribe = outerSubscribe(observeState)

return { unsubscribe }

},

[$$observable]() {

return this

}

}

}


//初始化時的action
dispatch({ type: ActionTypes.INIT })

//返回四個方法,分別完成相應的功能
return {

    dispatch,
    subscribe,
    getState,
    replaceReducer,
    [$$observable]: observable
}
}

當我們使用createStore(reducer)函數(shù)時丘逸,會返回四個方法供我們使用单鹿。當用戶在view層進行數(shù)據(jù)操作時,這時就有相應的action產(chǎn)生深纲,使用store.dispatch(action)來執(zhí)行reducer函數(shù)對state進行更新仲锄,這樣通過getState()就可以獲取最新的state在組件中進行動態(tài)顯示。

大家可以通過官網(wǎng)上的Counter實例驗證一下湃鹊。

代碼地址:https://github.com/reactjs/redux/tree/master/examples/counter

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末儒喊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子币呵,更是在濱河造成了極大的恐慌怀愧,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芯义,居然都是意外死亡哈垢,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門毕贼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來温赔,“玉大人,你說我怎么就攤上這事鬼癣√赵簦” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵待秃,是天一觀的道長拜秧。 經(jīng)常有香客問我,道長章郁,這世上最難降的妖魔是什么枉氮? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮暖庄,結(jié)果婚禮上聊替,老公的妹妹穿的比我還像新娘。我一直安慰自己培廓,他們只是感情好惹悄,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肩钠,像睡著了一般泣港。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上价匠,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天当纱,我揣著相機與錄音,去河邊找鬼踩窖。 笑死坡氯,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的洋腮。 我是一名探鬼主播廉沮,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼徐矩!你這毒婦竟也來了滞时?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤滤灯,失蹤者是張志新(化名)和其女友劉穎坪稽,沒想到半個月后曼玩,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡窒百,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年黍判,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片篙梢。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡顷帖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渤滞,到底是詐尸還是另有隱情贬墩,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布妄呕,位于F島的核電站陶舞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绪励。R本人自食惡果不足惜肿孵,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疏魏。 院中可真熱鬧停做,春花似錦、人聲如沸大莫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽葵硕。三九已至,卻和暖如春贯吓,著一層夾襖步出監(jiān)牢的瞬間懈凹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工悄谐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留介评,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓爬舰,卻偏偏與公主長得像们陆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子情屹,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 前言 redux并不局限于flux與react坪仇。redux 自身保持簡潔以便適配各種場景,讓社區(qū)發(fā)展出各種 red...
    yeatszhang閱讀 717評論 0 49
  • http://gaearon.github.io/redux/index.html 垃你,文檔在 http://rac...
    jacobbubu閱讀 79,959評論 35 198
  • "react-redux": "^5.0.6" redux和react之間的橋梁是react的context椅文,re...
    別過經(jīng)年閱讀 745評論 0 1
  • 一喂很、CMS管理系統(tǒng)功能 CMS是ContentManagementSystem的縮寫,意為"內(nèi)容管理系統(tǒng)"皆刺。 CM...
    默默先生Alec閱讀 5,346評論 0 7
  • 原來喜歡一個人是這樣的感覺少辣。 我從不知道。 思念羡蛾、心焦漓帅、和欣喜若狂。 然而有一天痴怨,我的世界變成了無窮無盡的黑暗忙干, ...
    ouenglli閱讀 194評論 0 0