手动实现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);
相关文章
相关标签/搜索