手動實現redux(二)

一個app中store(狀態樹)是惟一的

咱們知道對於一個app, store應該是惟一,集中用reducer管理的,那麼當app中有多個頁面,每一個頁面有多個組件時,就應該有多個reducer來管理。
當我某個組件dispatch出去一個action(動做)時,store接收到action,應該交給誰來管理呢?這裏咱們暫時沒法使store根據不一樣的action來交由相應的reducer處理。

combineReducer

combineReducer函數將多個不一樣的reducer整合在一塊兒,而後返回一個整合後的reducer, 也就是一個函數;函數內部經過分治的方式處理不一樣的action;

代碼實現

注意combineReducer函數仍然屬於reduxde一部分, 因此咱們只須要在上一節的代碼中添加便可。redux

let combineReducer = (reducersObj){
                    //        reducerObj是一個由全部所需reducer組成的對象
        return (state={}, action={ type: Symbol() })=>{
                    //        返回值其實就是一個rootReducer, 因此參數是state, action 
                    //         注意這個rootReducer其實就是在建立store的時候傳入的reducer. 
                    //        上一節中,建立store的時候須要先調用一下reducer(), 以獲得state的默認狀態值;此時至關於調用rootReducer({}, {type; Symbol()}) 
                    //        因此這裏給action設置了一個默認值, 注意這裏使用了Symbol這樣會是action.type沒法匹配到用戶定義任何的actionTypes 
                    //        rootReducer會返回一個新的state 
        let newState = {};
                    //        當咱們接收到一個action時,咱們沒法知道該交由哪一個reducer處理, 因此這裏咱們 須要遍歷全部reducer 
        for (let key in reducersObj){
          newState[key]  =  reducersObj[key](state[key], action)
                    //        這樣一個reducer就成爲了store狀態樹中的子樹 
                    //         好比頁面中有todo, counter兩個組件對應着兩個reducer, reducersObj = {todo, counter} 
                    //        store狀態樹大概長這樣: {todo: {list: [], counter: {number : 0}} 
        }
        return newState;
    }
}

最後將 combineReducer導出便可

combineReducer使用

通常來講,在一個app項目目錄中,咱們都會將reducer獨立出來,創建一個reducers文件夾,裏面就是各個app中所需的reducer, 而後這個文件夾裏還有一個index.js文件app

  1. 在這個index.js中咱們一般會先引入全部的reducer,而且引入combineReducer
    函數

    import counter from './counter';
     ...
     import todo from './todo';
     import { combineReducers } from "./../redux";
    
     const rootReducer = combineReducers({
         counter,
         todo,
         ....
     });
     export default rootReducer;
  2. 在store.js文件中引入rootReducer
    spa

    import { createStore } from "redux";
     import rootReducers from "./reducers/index";
     export default const store = createStore(rootReducers);
相關文章
相關標籤/搜索