深度减速器

时间:2017-11-05 15:44:30

标签: react-redux

我有一个看起来像这样的初始状态(为了这个问题而简化):

export default {
  anObject: {
    parameters: {
      param1:'Foo',
      param2:'Bar'
    },
    someOtherProperty:'value'
  }
};

我有一个anObject部分的缩减器,用于处理parameter的更改。我有一个操作,它传递了要更改的参数的id以及该参数的newValue。减速器(再次,非常简单)看起来像这样:

import * as types from '../actions/actionTypes';
import initialState from './initialState';

export default function anObjectReducer(state = initialState.anObject, action){

 switch(action.type){

    case types.UPDATE_PARAMETER:
      return Object.assign(
        {},
        state,
        {
          parameters:Object.assign(
            {},
            state.parameters,
            { [action.id]: action.newValue })
        });

    default:
      return state;
  }
}

这个减速器对我来说不对。我以为我可以这样做:

case types.UPDATE_PARAMETER:
    return Object.assign({},state,{parameters:{[action.id]:action.newValue}});

但这似乎消灭了所有其他参数,只更新了正在更改的单个参数。我是否遗漏了一些关于如何构造减速机的明显信息?

如果它是相关的,这就是我设置root减速器的方式:

 import { combineReducers } from 'redux';
 import anObject from './anObjectReducer';
 export default combineReducers({
  anObject
 });

我认为可能有一种方法可以为每个对象的各个部分组成缩减器 - 也就是说,在我的示例中,parameterssomeOtherProperty部分anObject分开?

2 个答案:

答案 0 :(得分:1)

它消除其他参数的原因是因为您没有通过Object.assign中的先前值。

你应该这样做:

return Object.assign({}, state, {
  parameters: Object.assign({}, { [action.id]: action.newValue }),
});

或使用ES6传播语法:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator

return {
  ...state,
  parameters: {
    ...state.parameters,
    [action.id]: action.newValue,
  }
}

答案 1 :(得分:0)

您可以:

  1. 重组减速器:您不能将combineReducers仅用于商店的根目录。这种存储方式和动作一样,但是嵌套对象的缩减器变得轻巧

  2. 重组您的状态(和简化器)以使其尽可能平坦。需要付出更多的努力,但是通常它也使获取mapStateToProps中的数据变得更加容易。 normalizr应该通过封装与现有API的集成来帮助简化过渡 需要特定的数据结构

  3. 使用immer来编写代码,就像在改变状态一样。如果您正在学习React,这绝对不是一个好主意,但我会考虑在小型实际项目中使用它