成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

理解 Redux

leejan97 / 1049人閱讀

摘要:我們知道狀態(tài)機是表示有限個狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動作等行為的數(shù)學(xué)模型。對照上面我們自己寫的狀態(tài)機代碼可以看出的作用告訴狀態(tài)樹發(fā)生什么變化,及所需要的數(shù)據(jù)是什么。

前言

我之前開發(fā)網(wǎng)站的時候一直用的是 Flux, 自從出了 Redux 之后由于種種原因沒有跟進了解,最近手頭上的事情基本忙的差不多了,抽空閱讀了 Redux 的源碼,并整理了這篇博文。

先說重點: Redux 與 React 沒有關(guān)系,就好像 Javascript 和 Java ,雷鋒和雷峰塔的關(guān)系一樣。 Redux 旨在處理數(shù)據(jù)的流動。

Redux 是 JavaScript 狀態(tài)容器,提供可預(yù)測化的狀態(tài)管理。 Redux 是由 Flux 演變而來。

那么 Flux 是什么? Flux 在這里并不是一個框架,而是提供了一套數(shù)據(jù)流動的方案,類似 MVVM 的概念。

一些概念點 狀態(tài)容器

Redux 是一個狀態(tài)容器,這句話挺難理解的,下面的分析也是我的個人見解,不見得正確,歡迎指正。

我們知道狀態(tài)機是表示有限個狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動作等行為的數(shù)學(xué)模型。

例子:
有一個提供簡單加減計算的二則運算的算法。初始值為0,可以增加一個值和減去一個值。

可以如下自己實現(xiàn)一個狀態(tài)機:

const fsm = {
    currentState: 0,
    create(state) { this.currentState = state },
    getState() {
        return this. currentState
    },
    transition(action) {
        switch(action.type) {
            case "add": 
                this.currentState =  this.currentState + action.num
                break
            case "sub": 
                this.currentState =  this.currentState - action.num
                break    
            default:
                break
        } 
    }
}

fsm.create(5)
fsm.transition({"type":"add", "num":-1})
console.log(fsm.getState())   // ==>  4
fsm.transition({"type":"sub", "num":1})
console.log(fsm.getState())   // ==>  3

從上面的例子可以看到狀態(tài)的改變方式為:輸入初始狀態(tài)值5,此時的 currentState 為0,輸入{"type":"add", "num": 1},經(jīng)過條件判斷是要將狀態(tài)值 5 加 -1 變成 4,再輸入{"type":"sub", "num": 1},經(jīng)過條件判斷是要將狀態(tài)值 4 減 1 變成 3。

對比 Redux 來看的話, 我們的 fsm 就是 Redux 的 createStore 返回的 store,store.getState() 返回的狀態(tài)對應(yīng) fsm.getState()。 那么 reducer + dispatch + action 對應(yīng)的就是 fsm.transition()。之后會我們分析源碼看看 Redux 是怎樣把 reducer + dispatch + action 轉(zhuǎn)成 fsm.transition。

整理了一張 Redux 的狀態(tài)圖如下:

對于 Redux 來說,就是把數(shù)據(jù)當成狀態(tài)來處理,reducer 就是根據(jù)行為(action) 將當前數(shù)據(jù)(狀態(tài))轉(zhuǎn)成新的狀態(tài),新的數(shù)據(jù)狀態(tài)可以繼續(xù)被 reducer 處理。

Action

Action 是把數(shù)據(jù)從應(yīng)用傳到 stateTree(狀態(tài)樹)的輸入動作(payloads)。按照約定來說 action 是一個帶有 type 屬性的 javascript plain object,對應(yīng)著 Flux 中的 payload。

Action Creator 是一個創(chuàng)建 Action 的函數(shù),額,其實就是函數(shù)式編程搞出的概念,把一個表達式包裝成一個函數(shù),返回這個 Action。

對照上面我們自己寫的狀態(tài)機代碼可以看出 action 的作用告訴 statetree (狀態(tài)樹)發(fā)生什么變化,及所需要的數(shù)據(jù)是什么。

Reducer

Reducer 的是根據(jù) action 來決定數(shù)據(jù)應(yīng)該變化成什么樣子的函數(shù),即將上面 fsm 中的switch case 表達式包裝而成的函數(shù)。

Dispatch

dispatch 是更新狀態(tài)樹的方法,在 dispatch 中會調(diào)用 reducer, 且通知監(jiān)聽者數(shù)據(jù)已發(fā)生變化。

從上面的分析應(yīng)該可以推斷出 Redux 暴露的 dispatch 會接受一個 action,來決定根據(jù) reducer 去轉(zhuǎn)換狀態(tài)樹,那么也可以推斷出 Redux 一定也需要提供一個接受 reducer 函數(shù)的API。

Redux 提供的 createStore(reducers, initialState) API 確實如我們推斷,會在此時傳入 reducer,以及一個可選的初始狀態(tài)。 createStore 返回的是一個 store, store 和狀態(tài)樹是不同的,此處的store具有dispatch(action) 方法的對象,真正的狀態(tài)樹是 store.getState()(也就是我們真正要使用的數(shù)據(jù))。

Redux 的部分源碼分析
export default function createStore(reducer, initialState) {
  // 在調(diào)用 createStore 的時候,必須傳入 reducer, 且 reducer 必須為函數(shù)
  if (typeof reducer !== "function") {
    throw new Error("Expected the reducer to be a function.")
  }

  var currentReducer = reducer
  var currentState = initialState
  var listeners = []
  var isDispatching = false
  
  // 返回此時的狀態(tài)
  function getState() {
    return currentState
  }

  // 訂閱函數(shù),調(diào)用 dispatch 的時候會調(diào)用 listener
  function subscribe(listener) {
        // ...
  }

  // 發(fā)布函數(shù), 在 action 觸發(fā)狀態(tài)的改變后,通知所有訂閱的 listener
  function dispatch(action) {
    // 傳入的 action 必須為 plain object,也就是 action creator 返回的對象
    // 自己傳入 action 對象也是可以的
    // 但是 Redux 推薦的寫法是 action creator 的寫法
    // 至于寫成函數(shù)的好處不在這里討論
    if (!isPlainObject(action)) {
      throw new Error(
        "Actions must be plain objects. " +
        "Use custom middleware for async actions."
      )
    }

    // 強制要求 action 必須帶入 type 屬性,比 Flux 有更強的約束
    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
      // 這里就是把 action 和當前狀態(tài)經(jīng)過 reducer 處理之后返回一個新的狀態(tài)
      // currentReducer 就是 createStore 傳進來的 reducer
      // 可以切回去看看上面我總結(jié)的圖
      currentState = currentReducer(currentState, action)
    } finally {
      isDispatching = false
    }
    // 通知訂閱的事件
    listeners.slice().forEach(listener => listener())
    return action
  }

  // 狀態(tài)初始話,此時的 Action 為 { type: ActionTypes.INIT }
  dispatch({ type: ActionTypes.INIT })

  // createStore 最后返回一個罕有 dispatch 和 getState 的對象
  return {
    dispatch,
    subscribe,
    getState,
    replaceReducer
  }
}
總結(jié)

Redux 就像是作者自己的介紹,是一個 JavasSript 的狀態(tài)容器,所有的數(shù)據(jù)(狀態(tài))的變化都是當前狀態(tài)和 Action 共同的作用結(jié)果。 對于使用者(一般都是指 view)來說,不用關(guān)心數(shù)據(jù)是怎樣變化,只需要在 view 層面等待 store 通知自己數(shù)據(jù)發(fā)生變化,然后把數(shù)據(jù)渲染成頁面即可。

這里沒有提到 Redux 的另一個比較重要也比較難理解的 Middleware。因為如果在這里說的的話,文章不知道要寫多長,而長文我現(xiàn)在也駕馭不住,所以干脆就不寫了,后面我會再補一篇理解 Middleware 的文章。

開個腦洞

其實我對 Redux 的這種實現(xiàn)狀態(tài)的方式并不太喜歡,相對來說 javascript-state-machine 看起來更舒服一些,不知道和 Redux 結(jié)合有什么效果。可能畫面太美,我不敢想?。

原文 @github

作者 @zwhu

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

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

相關(guān)文章

  • 深入理解redux

    摘要:深入簡述在快速理解中,我簡單的介紹了的基礎(chǔ)內(nèi)容,本篇文章中,我們將再度深入。二修改我曾在快速理解中提起,為了解決模塊組件之間需要共享數(shù)據(jù)和數(shù)據(jù)可能被任意修改導(dǎo)致不可預(yù)料的結(jié)果的矛盾,團隊創(chuàng)建了。 深入Redux 簡述 在快速理解redux中,我簡單的介紹了redux的基礎(chǔ)內(nèi)容,本篇文章中,我們將再度深入redux。 redux解決的問題 數(shù)據(jù)和函數(shù)的層層傳遞 多個組件同時修改某全局變...

    pekonchan 評論0 收藏0
  • redux和react-redux理解和總結(jié)(一)

    摘要:使得在變化和異步中可預(yù)測。它是數(shù)據(jù)的唯一來源。指定了應(yīng)用狀態(tài)的變化如何響應(yīng)并發(fā)送到的,只是描述了有事情發(fā)生了這一事實,并沒有描述應(yīng)用如何更新。更新的函數(shù)稱為,它是一個純函數(shù),接受舊的和,返回新的。是和之間的橋梁,是把它們聯(lián)系到一起的對象。 為什么使用redux 隨著前端單頁面開發(fā)越來越復(fù)雜,javascript需要管理越來越多的狀態(tài)state。如果一個model的變化引起另一個mode...

    skinner 評論0 收藏0
  • Redux之旅-1

    摘要:我們約定,內(nèi)使用一個字符串類型的字段來表示將要執(zhí)行的動作。多數(shù)情況下,會被定義成字符串常量。要進去工廠加工產(chǎn)品,就得帶上相應(yīng)得鑰匙,不同的鑰匙對應(yīng)工廠中上不同的生產(chǎn)線里面的函數(shù),從而有不同的產(chǎn)出改變之后的 時間:2016.4.7-17:24作者:三月懶驢入門配置文章:鏈接 準備 在你的項目下面加入redux / react-redux npm install redux --s...

    hiyang 評論0 收藏0
  • Redux原理分析

    摘要:調(diào)用鏈中最后一個會接受真實的的方法作為參數(shù),并借此結(jié)束調(diào)用鏈??偨Y(jié)我們常用的一般是除了和之外的方法,那個理解明白了,對于以后出現(xiàn)的問題會有很大幫助,本文只是針對最基礎(chǔ)的進行解析,之后有機會繼續(xù)解析對他的封裝 前言 雖然一直使用redux+react-redux,但是并沒有真正去講redux最基礎(chǔ)的部分理解透徹,我覺得理解明白redux會對react-redux有一個透徹的理解。 其實,...

    sumory 評論0 收藏0
  • 精讀《重新思考 Redux

    摘要:本周精讀內(nèi)容是重新思考。數(shù)據(jù)流對數(shù)據(jù)緩存,性能優(yōu)化,開發(fā)體驗優(yōu)化都有進一步施展的空間,擁抱插件生態(tài)是一個良好的發(fā)展方向。 本周精讀內(nèi)容是 《重新思考 Redux》。 1 引言 《重新思考 Redux》是 rematch 作者 Shawn McKay 寫的一篇干貨軟文。 dva 之后,有許多基于 redux 的狀態(tài)管理框架,但大部分都很局限,甚至是倒退。但直到看到了 rematch,總算...

    IntMain 評論0 收藏0

發(fā)表評論

0條評論

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