• Redux API之combineReducers


    combineReducers(reducers)

    随着应用变得复杂,需要对 reducer 函数 进行拆分,拆分后的每一块独立负责管理 state 的一部分。

    combineReducers 辅助函数的作用是,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore

    合并后的 reducer 可以调用各个子 reducer,并把它们的结果合并成一个 state 对象。state 对象的结构由传入的多个 reducer 的 key 决定

    最终,state 对象的结构会是这样的:

    {
      reducer1: ...
      reducer2: ...
    }
    

    通过为传入对象的 reducer 命名不同来控制 state key 的命名。例如,你可以调用 combineReducers({todos: myTodosReducer, counter: myCounterReducer }) 将 state 结构变为 { todos, counter }

    通常的做法是命名 reducer,然后 state 再去分割那些信息,因此你可以使用 ES6 的简写方法:combineReducers({ counter, todos })。这与 combineReducers({ counter: counter, todos: todos })一样。

    Flux 用户使用须知

    本函数可以帮助你组织多个 reducer,使它们分别管理自身相关联的 state。类似于 Flux 中的多个 store 分别管理不同的 state。在 Redux 中,只有一个 store,但是 combineReducers 让你拥有多个 reducer,同时保持各自负责逻辑块的独立性。

    参数

    1. reducers (Object): 一个对象,它的值(value) 对应不同的 reducer 函数,这些 reducer 函数后面会被合并成一个。下面会介绍传入 reducer 函数需要满足的规则。

    之前的文档曾建议使用 ES6 的 import * as reducers 语法来获得 reducer 对象。这一点造成了很多疑问,因此现在建议在 reducers/index.js 里使用 combineReducers() 来对外输出一个 reducer。下面有示例说明。

    返回值

    (Function):一个调用 reducers 对象里所有 reducer 的 reducer,并且构造一个与 reducers 对象结构相同的 state 对象。

    注意

    本函数设计的时候有点偏主观,就是为了避免新手犯一些常见错误。也因些我们故意设定一些规则,但如果你自己手动编写根 redcuer 时并不需要遵守这些规则。

    每个传入 combineReducers 的 reducer 都需满足以下规则:

    • 所有未匹配到的 action,必须把它接收到的第一个参数也就是那个 state 原封不动返回。

    • 永远不能返回 undefined。当过早 return 时非常容易犯这个错误,为了避免错误扩散,遇到这种情况时 combineReducers 会抛异常。

    • 如果传入的 state 就是 undefined,一定要返回对应 reducer 的初始 state。根据上一条规则,初始 state 禁止使用 undefined。使用 ES6 的默认参数值语法来设置初始 state 很容易,但你也可以手动检查第一个参数是否为 undefined

    虽然 combineReducers 自动帮你检查 reducer 是否符合以上规则,但你也应该牢记,并尽量遵守。

    示例

     1 reducers/todos.js
     2 
     3 export default function todos(state = [], action) {
     4   switch (action.type) {
     5   case 'ADD_TODO':
     6     return state.concat([action.text])
     7   default:
     8     return state
     9   }
    10 }
    11 reducers/counter.js
    12 
    13 export default function counter(state = 0, action) {
    14   switch (action.type) {
    15   case 'INCREMENT':
    16     return state + 1
    17   case 'DECREMENT':
    18     return state - 1
    19   default:
    20     return state
    21   }
    22 }
    23 reducers/index.js
    24 
    25 import { combineReducers } from 'redux'
    26 import todos from './todos'
    27 import counter from './counter'
    28 
    29 export default combineReducers({
    30   todos,
    31   counter
    32 })
    33 App.js
    34 
    35 import { createStore } from 'redux'
    36 import reducer from './reducers/index'
    37 
    38 let store = createStore(reducer)
    39 console.log(store.getState())
    40 // {
    41 //   counter: 0,
    42 //   todos: []
    43 // }
    44 
    45 store.dispatch({
    46   type: 'ADD_TODO',
    47   text: 'Use Redux'
    48 })
    49 console.log(store.getState())
    50 // {
    51 //   counter: 0,
    52 //   todos: [ 'Use Redux' ]
    53 // }
    View Code

    小贴士

    • 本方法只是起辅助作用!你可以自行实现不同功能的 combineReducers,甚至像实现其它函数一样,明确地写一个根 reducer 函数,用它把子 reducer 手动组装成 state 对象。

    • 在 reducer 层级的任何一级都可以调用 combineReducers。并不是一定要在最外层。实际上,你可以把一些复杂的子 reducer 拆分成单独的孙子级 reducer,甚至更多层。

  • 相关阅读:
    canvas和svg
    表单控件及表单属性
    ajax
    数据结构与算法经典问题解析-Java语言描述
    SpringBoot
    ThreadLocal 原理
    代理模式-结构型
    框架面试
    Hash算法总结
    集合与多线程面试
  • 原文地址:https://www.cnblogs.com/ZSG-DoBestMe/p/5280141.html
Copyright © 2020-2023  润新知