正确使用减速器

Ami*_*.io 31 reducers redux

我不明白减压器是什么意思.如果我有2个包含相同动作的reducer功能,它是否可以使用?

function reducerA(state, action){
   switch(action.type):
       ...
       case 'SAME_ACTION': {...state, field: state.field+1}
}

function reducerB(state, action){
   switch(action.type):
       ...
       case 'SAME_ACTION': {...state, field: state.field*2}
}
Run Code Online (Sandbox Code Playgroud)

所以,如果我调用并且调用reduceReducer了动作"SAME_ACTION",那么我会有下一个状态吗?reducerAreducerB{field: 0}{field: 2}

在我看来,它有点连接缩减器(意味着将它们合并在一个键下).

我是对的还是reduceReducer服务于不同的目的?

Tom*_*ich 80

不同之处是:

  • combineReducers创建嵌套状态
  • reduceReducers创造平坦的状态

考虑以下减速器.没有动作类型可以简化事情:

// this reducer adds a payload to state.sum 
// and tracks total number of operations
function reducerAdd(state, payload) {
  if (!state) state = { sum: 0, totalOperations: 0 }
  if (!payload) return state

  return {
    ...state,
    sum: state.sum + payload,
    totalOperations: state.totalOperations + 1
  }
}

// this reducer multiplies state.product by payload
// and tracks total number of operations
function reducerMult(state, payload) {
  if (!state) state = { product: 1, totalOperations: 0 }
  if (!payload) return state

  // `product` might be undefined because of 
  // small caveat in `reduceReducers`, see below
  const prev = state.product || 1

  return {
    ...state,
    product: prev * payload,
    totalOperations: state.totalOperations + 1
  }
}
Run Code Online (Sandbox Code Playgroud)

combineReducers

每个reducer都有一个独立的状态(另请参见http://redux.js.org/docs/api/combineReducers.html):

const rootReducer = combineReducers({
  add: reducerAdd,
  mult: reducerMult
})

const initialState = rootReducer(undefined)
/*
 * {
 *   add:  { sum: 0, totalOperations: 0 },
 *   mult: { product: 1, totalOperations: 0 },
 * }
 */


const first = rootReducer(initialState, 4)
/*
 * {
 *   add:  { sum: 4, totalOperations: 1 },
 *   mult: { product: 4, totalOperations: 1 },
 * }
 */    
// This isn't interesting, let's look at second call...

const second = rootReducer(first, 4)
/*
 * {
 *   add:  { sum: 8, totalOperations: 2 },
 *   mult: { product: 16, totalOperations: 2 },
 * }
 */
// Now it's obvious, that both reducers get their own 
// piece of state to work with
Run Code Online (Sandbox Code Playgroud)

reduceReducers

所有减速器具有相同的状态

const addAndMult = reduceReducers(reducerAdd, reducerMult) 

const initial = addAndMult(undefined)
/* 
 * {
 *   sum: 0,
 *   totalOperations: 0
 * }
 *
 * First, reducerAdd is called, which gives us initial state { sum: 0 }
 * Second, reducerMult is called, which doesn't have payload, so it 
 * just returns state unchanged. 
 * That's why there isn't any `product` prop.
 */ 

const next = addAndMult(initial, 4)
/* 
 * {
 *   sum: 4,
 *   product: 4,
 *   totalOperations: 2
 * }
 *
 * First, reducerAdd is called, which changes `sum` = 0 + 4 = 4
 * Second, reducerMult is called, which changes `product` = 1 * 4 = 4
 * Both reducers modify `totalOperations`
 */


const final = addAndMult(next, 4)
/* 
 * {
 *   sum: 8,
 *   product: 16,
 *   totalOperations: 4
 * }
 */
Run Code Online (Sandbox Code Playgroud)

用例

  • combineReducers- 每个reducer管理自己的状态片段(例如state.todosstate.logging).这在创建减速器时很有用.
  • reduceReducers - 每个reducer管理相同的状态.链,这是为了在相同的状态(使用结合几个减速创建时,这可能发生在例如操作几个减速时,这是非常有用handleAction终极版-行动)

从最终的状态形状来看,差异是显而易见的.

注意事项

有一个小警告reduceReducers:当调用最终的reducer时state = undefined,它应该返回初始状态.但是,只有链中的第一个减速器得到undefined,所有其他减速器将从第一个减速器接收状态.