對於 redux 的一些理解-1.基礎

最近從 https://github.com/frontend9 上看了下博主對 redux 學習過程的一個分享 , 講解的很是仔細易懂 , 感興趣的建議從博主的 https://github.com/brickspert/blog/issues/22 案例中去逐個學習理解(動手敲) , 相信必定可以對 redux的使用有個完全的理解;html

 

咱們從中文文檔中能夠看到這樣的話:git

 

'隨着 JavaScript 單頁應用開發日趨複雜,JavaScript 須要管理比任什麼時候候都要多的 state (狀態)。 這些 state 可能包括服務器響應、緩存數據、本地生成還沒有持久化到服務器的數據,也包括 UI 狀態,如激活的路由,被選中的標籤,是否顯示加載動效或者分頁器等等'github

Redux 試圖讓 state 的變化變得可預測。這些限制條件反映在了 redux 的三大原則中ajax

1:單一數據源redux

2:state 是隻讀的緩存

3:使用純函數來執行修改服務器

 

假設你歷來沒有用過 redux, 拋棄這些名詞, 回到原始的開發模式。使用 ajax 從服務器請求數據, 根據數據生成 html片斷, 插入到指定的 dom節點。邏輯很簡單根本就不須要使用框架, 就能夠得到很好的開發和瀏覽體驗。框架

當單頁面模式推崇以後 , 全部的操做都在一個 html文件中去處理, 狀況變得複雜起來了。在一個頁面中你須要處理各個模塊的邏輯 , 你要不斷去處理數據的更新, 添加, 刪除; 這時候若是不對數據修改加以約束(隨處可見的修改, 跨頁面的修改等), 會難以追蹤到你的數據走向。frontend

尤爲是對於引用類型數據, 對某一處不經意的修改, 簡直會讓人崩潰(你不知道到底在哪裏做了修改, 可能就發生在某一個函數的調用中, 好比對形參 param.a = 1 這種操做)。dom

這時候也有人推出了深複製的解決辦法, 每次都是操做一個全新的對象, 對源數據不會形成任何影響, 思路固然沒錯. 可這距離咱們指望的結果: 對於數據的每一次修改都是可監測可控制的。仍是有些差距。

 

Redux 的推出可謂是一種很好的解決方案。正如 redux文檔自述中所言: Redux 是 JavaScript 狀態容器,提供可預測化的狀態管理

正由於它堅持的三大原則

1. 單一數據源; 避免了咱們在各個模塊中去重複複製, 重複定義, 這對於整個應用的數據更新都會帶來麻煩; 要麼只在模塊內部去定義, 要麼定義在全局(單一數據源上), 不推薦在內部定義一個, 在全局又定義一個同一用途的數據;

2. state 是隻讀的, redux提供了惟一改變 state 的方法就是觸發 action; 它們只能表達想要修改的意圖,

3. 使用純函數來執行修改;

  咱們來看一看執行修改的邏輯就明白了:

function changeCount(state={}, action){
    switch(action.type) {
        case 'INCREMENT':
            return {
                ...state,
                count: state.count + 1
            }
        default:
            return state
    }   
}

咱們對原狀態 state 沒有作任何修改, 只是返回了一個新的 state; 藉由此, 在處理邏輯時, 咱們能夠把應用上一次的 state, 和更新後的 state 都傳遞出去; 甚至咱們能夠改寫裏面的邏輯, 記錄下前幾回狀態值的修改;

始終記住 redux提供可預測化的狀態管理, 這就是它所作的工做。

 

 

/***********************    *************************************/

在之前本身去記錄應用狀態的作法多是這樣的;

function createStore (initData) {
    var APP_DATA = initData || {};

return { get: function (key) { return key ? APP_DATA[key] : APP_DATA; }, set: function (key, data) { APP_DATA[key] = data; } } } var Store = createStore(); function getUserInfo () { setTimeout(function () { var userInfo = { name: '張三', age: '23' }; Store.set('userInfo', userInfo); }, 100) } getUserInfo(); function validate () { return !!Store.get('userInfo'); } function submit () { var userInfo; if (validate()) { userInfo = Store.get('userInfo'); console.log(userInfo); } } setTimeout(submit, 300);

 

換做用 redux 可能得這樣

function createStore (reducer, initState) {
    var listeners = [];
    var store = initState;
    
    function getState () {
        return store;
    }
    
    function subscribe (listen) {
        listeners.push(listen)
    }
    
    function dispatch (action) {
        store = reducer(store, action);
        for(var i = 0; i < listeners.length; i++) {
            listeners[i]()
        }
    }
    
    return {
        getState: getState,
        subscribe: subscribe,
        dispatch: dispatch
    }
}

function reducer (state, action) {
    switch (action.type) {
        case 'SET_USERINFO':
            return {
                ...state,
                userInfo: action.data
            }
        default:
            return state;
    }
}

var Store = createStore(reducer, {});

function getUserInfo () {
    setTimeout(function () {
        Store.dispatch({
            type: 'SET_USERINFO',
            data: { name: '張三', age: '23' }
        });
    }, 100)
}
getUserInfo();

function validate () {
    return !!Store.getState().userInfo;
}

function submit () {
    var userInfo;
    if (validate()) {
        userInfo = Store.getState().userInfo;
        
        console.log(userInfo);
    }
}

setTimeout(submit, 300);

應該用什麼樣的方式去管理應用狀態 , 這個問題或許太寬泛沒法回答 , 我只能說踩過的一些坑 , 也是對以前的"錯誤作法"一些總結:

1. 賦值操做時要格外當心 , 尤爲是引用; 

2. 避免兀餘的數據 , 這時咱們經常會定義些 "全局變量" , 來保存多個位置的相同信息。儘可能去約束脩改的行爲

3. 保護好你的應用數據 。不得已 能夠經過重置的手段還原到初始狀態。

 

 

/***********************  補充  *************************************/

對於 redux 本身也存在些疑惑的地方 , 在下面暫且把它視做 redux 的缺陷吧

1. redux 的 action 分發機制: 在源碼中 action 被自頂往下層層傳遞 , 也就意味全部的下級狀態都會接受到消息 , 那也就可能存在 有多個下級狀態 同時作出響應 ---- 只要 action.type 不是惟一, 那麼就必然會出現這種狀況

  這一點能夠被利用來作一些特定場景 , 但糟糕的設想是: 一個應用中有 未知數相同的 action.type, 在某一處的修改觸發了全部狀態的修改 ;

  理想情況下 , 咱們應該只修改當前狀態的值 , 而不該擴寬它的影響範圍 , 所以稱它爲缺陷。 咱們在開發中應該儘可能對 action.type 命名惟一。

 

始終記住 redux提供可預測化的狀態管理。目前它並不完美 , 但足夠優秀。

相關文章
相關標籤/搜索