成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

解析 Redux 源碼

Batkid / 2879人閱讀

摘要:也可以看我的博客解析源碼解析源碼是狀態(tài)容器,提供可預(yù)測(cè)化的狀態(tài)管理。作為全家桶的一份子,可謂說(shuō)也是名聲響響,在年學(xué)習(xí)想必沒(méi)有多少人沒(méi)聽(tīng)過(guò)吧。

也可以看我的博客 - 解析 Redux 源碼

解析 Redux 源碼

TIP

Redux 是 JavaScript 狀態(tài)容器,提供可預(yù)測(cè)化的狀態(tài)管理。

作為 React 全家桶的一份子,Redux 可謂說(shuō)也是名聲響響,在 2016 年學(xué)習(xí) JavaScript 想必沒(méi)有多少人沒(méi)聽(tīng)過(guò)吧。

這里,本文不是來(lái)教大家如何使用 Redux 的 API 的,這一類(lèi)的文章已經(jīng)很多,對(duì)于 Redux 的介紹和學(xué)習(xí)可以點(diǎn)擊下列鏈接:

官方文檔

官方Github

中文文檔

redux 大法好 —— 入門(mén)實(shí)例 TodoList(本人的渣渣文章)

Redux 體小精悍(只有2kB)且沒(méi)有任何依賴,因此本文想通過(guò)閱讀 Redux 的源碼來(lái)學(xué)習(xí) Redux 的使用以及思想。

源碼結(jié)構(gòu)

Redux 的源碼結(jié)構(gòu)很簡(jiǎn)單,我們可以直接看 src 目錄下的代碼:

.src
├── utils                #工具函數(shù)
├── applyMiddleware.js
├── bindActionCreators.js        
├── combineReducers.js     
├── compose.js       
├── createStore.js  
└── index.js             #入口 js
index.js

這個(gè)是整個(gè)代碼的入口:

import createStore from "./createStore"
import combineReducers from "./combineReducers"
import bindActionCreators from "./bindActionCreators"
import applyMiddleware from "./applyMiddleware"
import compose from "./compose"
import warning from "./utils/warning"

function isCrushed() {}

if (
  process.env.NODE_ENV !== "production" &&
  typeof isCrushed.name === "string" &&
  isCrushed.name !== "isCrushed"
) {
  warning(
    "。。。"
  )
}

export {
  createStore,
  combineReducers,
  bindActionCreators,
  applyMiddleware,
  compose
}

這里的 isCrushed 函數(shù)主要是為了驗(yàn)證在非生產(chǎn)環(huán)境下 Redux 是否被壓縮(因?yàn)槿绻粔嚎s了那么 (isCrushed.name !== "isCrushed") 就是 true),如果被壓縮會(huì)給開(kāi)發(fā)者一個(gè) warn 提示)。

然后就是暴露 createStore combineReducers bindActionCreators applyMiddleware compose 這幾個(gè)接口給開(kāi)發(fā)者使用,我們來(lái)逐一解析這幾個(gè) API。

createStore.js

這個(gè)是 Redux 最主要的一個(gè) API 了,它創(chuàng)建一個(gè) Redux store 來(lái)以存放應(yīng)用中所有的 state,應(yīng)用中應(yīng)有且僅有一個(gè) store。

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

// 私有 action
export var ActionTypes = {
  INIT: "@@redux/INIT"
}

export default function createStore(reducer, preloadedState, enhancer) {
  // 判斷接受的參數(shù)個(gè)數(shù),來(lái)指定 reducer 、 preloadedState 和 enhancer
  if (typeof preloadedState === "function" && typeof enhancer === "undefined") {
    enhancer = preloadedState
    preloadedState = undefined
  }

  // 如果 enhancer 存在并且適合合法的函數(shù),那么調(diào)用 enhancer,并且終止當(dāng)前函數(shù)執(zhí)行
  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.")
  }

  // 儲(chǔ)存當(dāng)前的 currentReducer
  var currentReducer = reducer
  // 儲(chǔ)存當(dāng)前的狀態(tài)
  var currentState = preloadedState
  // 儲(chǔ)存當(dāng)前的監(jiān)聽(tīng)函數(shù)列表
  var currentListeners = []
  // 儲(chǔ)存下一個(gè)監(jiān)聽(tīng)函數(shù)列表
  var nextListeners = currentListeners
  var isDispatching = false

  // 這個(gè)函數(shù)可以根據(jù)當(dāng)前監(jiān)聽(tīng)函數(shù)的列表生成新的下一個(gè)監(jiān)聽(tīng)函數(shù)列表引用
  function ensureCanMutateNextListeners() {
    if (nextListeners === currentListeners) {
      nextListeners = currentListeners.slice()
    }
  }

  ... getState ...

  ... subscribe ...

  ... dispatch ...

  ... replaceReducer ...

  ... observable ...

  dispatch({ type: ActionTypes.INIT })

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

首先定義了一個(gè) ActionTypes 對(duì)象,它是一個(gè) action,是一個(gè) Redux 的私有 action,不允許外界觸發(fā),用來(lái)初始化 Store 的狀態(tài)樹(shù)和改變 reducers 后初始化 Store 的狀態(tài)樹(shù)。

createStore

然后著重來(lái)看 createStore 函數(shù):

接受

它可以接受三個(gè)參數(shù),reducer、preloadedState、enhancer:

reducer:是一個(gè)函數(shù),返回下一個(gè)狀態(tài),接受兩個(gè)參數(shù):當(dāng)前狀態(tài) 和 觸發(fā)的 action;

preloadedState:初始狀態(tài)對(duì)象,可以很隨意指定,比如服務(wù)端渲染的初始狀態(tài),但是如果使用 combineReducers 來(lái)生成 reducer,那必須保持狀態(tài)對(duì)象的 key 和 combineReducers 中的 key 相對(duì)應(yīng);

enhancer:store 的增強(qiáng)器函數(shù),可以指定為 第三方的中間件,時(shí)間旅行,持久化 等等,但是這個(gè)函數(shù)只能用 Redux 提供的 applyMiddleware 函數(shù)來(lái)生成;

根據(jù)傳入?yún)?shù)的個(gè)數(shù)和類(lèi)型,判斷 reducer 、 preloadedState 、 enhancer;

返回

調(diào)用完函數(shù)它返回的接口是 dispatch subscribe getState replaceReducer[$$observable]

這也是我們開(kāi)發(fā)中主要使用的幾個(gè)接口。

enhancer

如果 enhancer 參數(shù)傳入并且是個(gè)合法的函數(shù),那么就是調(diào)用 enhancer 函數(shù)(傳入 createStore 來(lái)給它操作),enhancer 函數(shù)返回的也是一個(gè)函數(shù),在這里傳入 reducerpreloadedState,并且返回函數(shù)調(diào)用結(jié)果,終止當(dāng)前函數(shù)執(zhí)行;
在 enhancer 函數(shù)里面是如何操作使用的可以看 applyMiddleware 部分;

getState
function getState() {
  return currentState
}

這個(gè)函數(shù)可以獲取當(dāng)前的狀態(tài),createStore 中的 currentState 儲(chǔ)存當(dāng)前的狀態(tài)樹(shù),這是一個(gè)閉包,這個(gè)參數(shù)會(huì)持久存在,并且所有的操作狀態(tài)都是改變這個(gè)引用,getState 函數(shù)返回當(dāng)前的 currentState。

subscribe
function subscribe(listener) {
  // 判斷傳入的參數(shù)是否為函數(shù)
  if (typeof listener !== "function") {
    throw new Error("Expected listener to be a function.")
  }

  var isSubscribed = true

  ensureCanMutateNextListeners()
  nextListeners.push(listener)

  return function unsubscribe() {
    if (!isSubscribed) {
      return
    }

    isSubscribed = false

    ensureCanMutateNextListeners()
    var index = nextListeners.indexOf(listener)
    nextListeners.splice(index, 1)
  }
}

這個(gè)函數(shù)可以給 store 的狀態(tài)添加訂閱監(jiān)聽(tīng)函數(shù),一旦調(diào)用 dispatch ,所有的監(jiān)聽(tīng)函數(shù)就會(huì)執(zhí)行;
nextListeners 就是儲(chǔ)存當(dāng)前監(jiān)聽(tīng)函數(shù)的列表,調(diào)用 subscribe,傳入一個(gè)函數(shù)作為參數(shù),那么就會(huì)給 nextListeners 列表 push 這個(gè)函數(shù);
同時(shí)調(diào)用 subscribe 函數(shù)會(huì)返回一個(gè) unsubscribe 函數(shù),用來(lái)解綁當(dāng)前傳入的函數(shù),同時(shí)在 subscribe 函數(shù)定義了一個(gè) isSubscribed 標(biāo)志變量來(lái)判斷當(dāng)前的訂閱是否已經(jīng)被解綁,解綁的操作就是從 nextListeners 列表中刪除當(dāng)前的監(jiān)聽(tīng)函數(shù)。

dispatch
function dispatch(action) {
  if (!isPlainObject(action)) {
    throw new Error(
      "Actions must be plain objects. " +
      "Use custom middleware for async actions."
    )
  }

  // 判斷 action 是否有 type{必須} 屬性
  if (typeof action.type === "undefined") {
    throw new Error(
      "Actions may not have an undefined "type" property. " +
      "Have you misspelled a constant?"
    )
  }

  // 如果正在 dispatch 則拋出錯(cuò)誤
  if (isDispatching) {
    throw new Error("Reducers may not dispatch actions.")
  }

  // 對(duì)拋出 error 的兼容,但是無(wú)論如何都會(huì)繼續(xù)執(zhí)行 isDispatching = false 的操作
  try {
    isDispatching = true
    // 使用 currentReducer 來(lái)操作傳入 當(dāng)前狀態(tài)和action,放回處理后的狀態(tài)
    currentState = currentReducer(currentState, action)
  } finally {
    isDispatching = false
  }

  var listeners = currentListeners = nextListeners
  for (var i = 0; i < listeners.length; i++) {
    var listener = listeners[i]
    listener()
  }

  return action
}

這個(gè)函數(shù)是用來(lái)觸發(fā)狀態(tài)改變的,他接受一個(gè) action 對(duì)象作為參數(shù),然后 reducer 根據(jù) action 的屬性 以及 當(dāng)前 store 的狀態(tài)來(lái)生成一個(gè)新的狀態(tài),賦予當(dāng)前狀態(tài),改變 store 的狀態(tài);
currentState = currentReducer(currentState, action);
這里的 currentReducer 是一個(gè)函數(shù),他接受兩個(gè)參數(shù):當(dāng)前狀態(tài) 和 action,然后返回計(jì)算出來(lái)的新的狀態(tài);
然后遍歷 nextListeners 列表,調(diào)用每個(gè)監(jiān)聽(tīng)函數(shù);

replaceReducer
function replaceReducer(nextReducer) {
  // 判斷參數(shù)是否是函數(shù)類(lèi)型
  if (typeof nextReducer !== "function") {
    throw new Error("Expected the nextReducer to be a function.")
  }

  currentReducer = nextReducer
  dispatch({ type: ActionTypes.INIT })
}

這個(gè)函數(shù)可以替換 store 當(dāng)前的 reducer 函數(shù),首先直接把 currentReducer = nextReducer,直接替換;
然后 dispatch({ type: ActionTypes.INIT }) ,用來(lái)初始化替換后 reducer 生成的初始化狀態(tài)并且賦予 store 的狀態(tài);

observable
function observable() {
  var outerSubscribe = subscribe
  return {
    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()
      var unsubscribe = outerSubscribe(observeState)
      return { unsubscribe }
    },

    [$$observable]() {
      return this
    }
  }
}

對(duì)于這個(gè)函數(shù),是不直接暴露給開(kāi)發(fā)者的,它提供了給其他觀察者模式/響應(yīng)式庫(kù)的交互操作,具體可看 https://github.com/zenparsing/es-observable

last

最后執(zhí)行 dispatch({ type: ActionTypes.INIT }),用來(lái)根據(jù) reducer 初始化 store 的狀態(tài)。

compose.js

compose 可以接受一組函數(shù)參數(shù),從右到左來(lái)組合多個(gè)函數(shù),然后返回一個(gè)組合函數(shù);

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  const last = funcs[funcs.length - 1]
  const rest = funcs.slice(0, -1)
  return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
}
applyMiddleware.js
export default function applyMiddleware(...middlewares) {
  // 這個(gè)返回的函數(shù)就是 enhancer,接受 createStore 函數(shù),再返回一個(gè)函數(shù),接受的其實(shí)只有 reducer 和 preloadedState;
  return (createStore) => (reducer, preloadedState, enhancer) => {
    var store = createStore(reducer, preloadedState, enhancer)
    var dispatch = store.dispatch
    var chain = []

    // 暴漏 getState 和 dispatch 給 第三方中間價(jià)使用
    var middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    // 創(chuàng)造第三方中間件使用 middlewareAPI 后返回的函數(shù)組成的數(shù)組
    chain = middlewares.map(middleware => middleware(middlewareAPI))

    // 結(jié)合這一組函數(shù) 和 dispatch 組成的新的 dispatch,然后這個(gè)暴漏給用戶使用,而原有的 store.dispatch 是不變的,但是不暴漏
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

applyMiddleware 函數(shù)的作用是組合 多個(gè) 中間件等等,然后返回一個(gè)函數(shù)(enhancer

還記得在 createStore 中的一段嗎:

if (typeof enhancer !== "undefined") {
  if (typeof enhancer !== "function") {
    throw new Error("Expected the enhancer to be a function.")
  }

  return enhancer(createStore)(reducer, preloadedState)
}

這里 enhancer === applyMiddleware(...);

然后再執(zhí)行 enhancer(createStore) 繼續(xù)之后的操作;

這里 enhancer(createStore) 等同于 (reducer, preloadedState, enhancer) => { ... }

然后再執(zhí)行 enhancer(createStore)(reducer, preloadedState)

再回到 applyMiddleware ,這里調(diào)用了 var store = createStore(reducer, preloadedState, enhancer) ;
如上所見(jiàn),這里執(zhí)行的時(shí)候已經(jīng)沒(méi)有 enhancer 參數(shù)了,因此會(huì)再次執(zhí)行 createStore 函數(shù)的全部部分,然后得到一個(gè)返回的實(shí)例 store;

之后會(huì)生成一個(gè)新的 dispatch ,先保存下來(lái)原生的 dispatchvar dispatch = store.dispatch;

var middlewareAPI = {
  getState: store.getState,
  dispatch: (action) => dispatch(action)
}

這一步是把 store 的 getStatedispatch 接口暴露給中間件來(lái)操作: chain = middlewares.map(middleware => middleware(middlewareAPI));

最后組合 全部中間件的返回值(函數(shù))chainstore.dispatch,然后返回新的 dispatchdispatch = compose(...chain)(store.dispatch)

這里的 dispatch 并不是原有的 store 的,而是經(jīng)過(guò)組合中間件之后新的 dispatch;

最后返回暴露給用戶的接口:

return {
  ...store,
  dispatch
}

主要還是 store 原有的接口,但是用新的 dispatch 替換了原有的;這個(gè)函數(shù)其實(shí)就是根據(jù)中間件和store的接口生成新的 dispatch 然后暴露給用戶。

combineReducers.js

這個(gè)函數(shù)可以組合一組 reducers(對(duì)象) ,然后返回一個(gè)新的 reducer 函數(shù)給 createStore 使用。

它接受一組 reducers 組成的對(duì)象,對(duì)象的 key 是對(duì)應(yīng) value(reducer函數(shù))的狀態(tài)名稱(chēng);

比如: { userInfo: getUserInfo, list: getList }

userInfo 是根據(jù) getUserInfo 函數(shù)計(jì)算出來(lái)的;

那么 store 里面的 state 結(jié)構(gòu)就會(huì)是: { userInfo: ..., list: ... }

export default function combineReducers(reducers) {

  // 根據(jù) reducers 生成最終合法的 finalReducers:value 為 函數(shù)
  var reducerKeys = Object.keys(reducers)
  var finalReducers = {}
  for (var i = 0; i < reducerKeys.length; i++) {
    var key = reducerKeys[i]

    if (process.env.NODE_ENV !== "production") {
      if (typeof reducers[key] === "undefined") {
        warning(`No reducer provided for key "${key}"`)
      }
    }

    if (typeof reducers[key] === "function") {
      finalReducers[key] = reducers[key]
    }
  }

  var finalReducerKeys = Object.keys(finalReducers)

  if (process.env.NODE_ENV !== "production") {
    var unexpectedKeyCache = {}
  }

  // 驗(yàn)證 reducer 是否合法
  var sanityError
  try {
    assertReducerSanity(finalReducers)
  } catch (e) {
    sanityError = e
  }

  // 返回最終生成的 reducer
  return function combination(state = {}, action) {
    if (sanityError) {
      throw sanityError
    }

    if (process.env.NODE_ENV !== "production") {
      var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache)
      if (warningMessage) {
        warning(warningMessage)
      }
    }

    var hasChanged = false
    var nextState = {}
    for (var i = 0; i < finalReducerKeys.length; i++) {
      var key = finalReducerKeys[i]
      var reducer = finalReducers[key]
      var previousStateForKey = state[key]
      var nextStateForKey = reducer(previousStateForKey, action)
      if (typeof nextStateForKey === "undefined") {
        var errorMessage = getUndefinedStateErrorMessage(key, action)
        throw new Error(errorMessage)
      }
      nextState[key] = nextStateForKey
      hasChanged = hasChanged || nextStateForKey !== previousStateForKey
    }
    // 遍歷一遍看是否改變,然后返回原有狀態(tài)值或者新的狀態(tài)值
    return hasChanged ? nextState : state
  }
}

最終返回一個(gè) combination 也就是真正傳入 createStore 的 reducer 函數(shù);

這是一個(gè)標(biāo)準(zhǔn)的 reducer 函數(shù),接受一個(gè)初始化狀態(tài) 和 一個(gè) action 參數(shù);

每次調(diào)用的時(shí)候會(huì)去遍歷 finalReducer (有效的 reducer 列表),獲取列表中每個(gè) reducer 對(duì)應(yīng)的先前狀態(tài): var previousStateForKey = state[key];
看到這里就應(yīng)該明白傳入的 reducers 組合為什么 key 要和 store 里面的 state 的 key 相對(duì)應(yīng);

然后得到當(dāng)前遍歷項(xiàng)的下一個(gè)狀態(tài): var nextStateForKey = reducer(previousStateForKey, action) ;
然后把它添加到整體的下一個(gè)狀態(tài): nextState[key] = nextStateForKey

每次遍歷會(huì)判斷整體狀態(tài)是否改變: hasChanged = hasChanged || nextStateForKey !== previousStateForKey

在最后,如果沒(méi)有改變就返回原有狀態(tài),如果改變了就返回新生成的狀態(tài)對(duì)象: return hasChanged ? nextState : state。

bindActionCreators.js

bindActionCreators 函數(shù)可以生成直接觸發(fā) action 的函數(shù);

實(shí)質(zhì)上它只說(shuō)做了這么一個(gè)操作 bindActionFoo = (...args) => dispatch(actionCreator(...args))

因此我們直接調(diào)用 bindActionFoo 函數(shù)就可以改變狀態(tài)了;

接受兩個(gè)參數(shù),一個(gè)是 actionCreators( actionCreator 組成的對(duì)象,key 對(duì)于生成的函數(shù)名/或者是一個(gè) actionCreator ),一個(gè)是 dispatch, store 實(shí)例中獲??;

function bindActionCreator(actionCreator, dispatch) {
  return (...args) => dispatch(actionCreator(...args))
}

export default function bindActionCreators(actionCreators, dispatch) {
  // 是一個(gè)函數(shù),直接返回一個(gè) bindActionCreator 函數(shù),這個(gè)函數(shù)調(diào)用 dispatch 觸發(fā) action
  if (typeof actionCreators === "function") {
    return bindActionCreator(actionCreators, dispatch)
  }

  if (typeof actionCreators !== "object" || actionCreators === null) {
    throw new Error(
      `bindActionCreators expected an object or a function, instead received ${actionCreators === null ? "null" : typeof actionCreators}. ` +
      `Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
    )
  }

  // 遍歷對(duì)象,然后對(duì)每個(gè)遍歷項(xiàng)的 actionCreator 生成函數(shù),將函數(shù)按照原來(lái)的 key 值放到一個(gè)對(duì)象中,最后返回這個(gè)對(duì)象
  var keys = Object.keys(actionCreators)
  var boundActionCreators = {}
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i]
    var actionCreator = actionCreators[key]
    if (typeof actionCreator === "function") {
      boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
    }
  }
  return boundActionCreators
}
總結(jié)

閱讀了一遍 Redux 的源碼,實(shí)在是太精妙了,少依賴,少耦合,純函數(shù)式。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/92349.html

相關(guān)文章

  • redux源碼解讀--applyMiddleware源碼解析

    摘要:的中間件主要是通過(guò)模塊實(shí)現(xiàn)的。返回的也是一個(gè)對(duì)象這個(gè)其實(shí)就是,各個(gè)中間件的最底層第三層的哪個(gè)函數(shù)組成的圓環(huán)函數(shù)構(gòu)成的這就是對(duì)源碼的一個(gè)整體解讀,水平有限,歡迎拍磚。后續(xù)的源碼解讀和測(cè)試?yán)涌梢躁P(guān)注源碼解讀倉(cāng)庫(kù) applyMiddleware源碼解析 中間件機(jī)制在redux中是強(qiáng)大且便捷的,利用redux的中間件我們能夠?qū)崿F(xiàn)日志記錄,異步調(diào)用等多種十分實(shí)用的功能。redux的中間件主要是...

    Atom 評(píng)論0 收藏0
  • 源碼解析redux-thunk

    摘要:的返回值是函數(shù),這個(gè)函數(shù)經(jīng)調(diào)用,傳入?yún)?shù),之后會(huì)在中間件鏈上進(jìn)行傳遞,只要保證每個(gè)中間件的參數(shù)是并且將傳遞給下一個(gè)中間件。 了解了Redux原理之后,我很好奇Redux中間件是怎么運(yùn)作的,于是選了最常用的redux-thunk進(jìn)行源碼分析。 此次分析用的redux-thunk源碼版本是2.2.0,redux源碼版本是3.7.2。并且需要了解Redux原理 redux中間件都是由redu...

    simpleapples 評(píng)論0 收藏0
  • redux源碼解讀--compose源碼解析

    摘要:源碼解析模塊的代碼十分簡(jiǎn)練,但是實(shí)現(xiàn)的作用卻是十分強(qiáng)大。只傳遞一個(gè)參數(shù)的時(shí)候,就直接把這個(gè)函數(shù)返回返回組合函數(shù)這就是對(duì)源碼的一個(gè)整體解讀,水平有限,歡迎拍磚。后續(xù)的源碼解讀和測(cè)試?yán)涌梢躁P(guān)注源碼解讀倉(cāng)庫(kù) compose源碼解析 compose模塊的代碼十分簡(jiǎn)練,但是實(shí)現(xiàn)的作用卻是十分強(qiáng)大。redux為何稱(chēng)為redux?有人說(shuō)就是reduce和flux的結(jié)合體,而reduce正是comp...

    lk20150415 評(píng)論0 收藏0
  • redux源碼解讀--createStore源碼解析

    摘要:源碼解析是最核心的模塊。比如,當(dāng)我們需要使用中間件的時(shí)候,就會(huì)像第三個(gè)參數(shù)傳遞一個(gè)返回值是一個(gè)。后續(xù)的源碼解讀和測(cè)試?yán)涌梢躁P(guān)注源碼解讀倉(cāng)庫(kù) createStore源碼解析 createStore是redux最核心的模塊。這個(gè)模塊就是用于創(chuàng)建一個(gè)store對(duì)象,同時(shí),對(duì)外暴露出dispatch,getState,subscribe和replaceReducer方法。(源碼中關(guān)于obse...

    tianren124 評(píng)論0 收藏0
  • Redux 源碼解析 - Redux 的架構(gòu)

    摘要:要應(yīng)用于生成環(huán)境必須要用或者,是的進(jìn)化產(chǎn)物,優(yōu)于。我們來(lái)看一下他的源碼,從而學(xué)一些東西。里面都是一個(gè)一個(gè)的模塊,一共個(gè)模塊,都導(dǎo)出了一些的方法,比如這個(gè)號(hào)函數(shù),一個(gè)匿名函數(shù),然后導(dǎo)出他寫(xiě)的方法。整體架構(gòu)就是這樣的。主要用于壓縮的時(shí)候。 redux很小的一個(gè)框架,是從flux演變過(guò)來(lái)的,盡管只有775行,但是它的功能很重要。react要應(yīng)用于生成環(huán)境必須要用flux或者redux,red...

    lylwyy2016 評(píng)論0 收藏0
  • redux源碼解析

    摘要:前言的源碼是我閱讀過(guò)的一些庫(kù)的源碼中,相對(duì)簡(jiǎn)單的。在更新完成后,同時(shí)會(huì)更新,并依次執(zhí)行監(jiān)聽(tīng)者列表。使用新的替換現(xiàn)有的,同時(shí)執(zhí)行是隨機(jī)的字符串。會(huì)為注冊(cè)監(jiān)聽(tīng)器,監(jiān)聽(tīng)器存儲(chǔ)在數(shù)組中,返回的函數(shù)則會(huì)注銷(xiāo)監(jiān)聽(tīng)器。使用管道,將逐層的進(jìn)行包裝 showImg(https://segmentfault.com/img/remote/1460000019425043?w=1380&h=810); sh...

    chanjarster 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

Batkid

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<