ReactJS - 在 reducer 中使用 immutability-helper 的正确方法

ReactJS - Proper way for using immutability-helper in reducer

我有以下对象,这是我在 reducer 中的初始状态:

const INITIAL_STATE = {
  campaign_dates: {
    dt_start: '',
    dt_end: '',
  },
  campaign_target: {
    target_number: '',
    gender: '',
    age_level: {
      age_start: '',
      age_end: '',
    },
    interest_area: [],
    geolocation: {},
  },
  campaign_products: {
    survey: {
      name: 'Survey',
      id_product: 1,
      quantity: 0,
      price: 125.0,
      surveys: {},
    },
    reward: {
      name: 'Reward',
      id_product: 2,
      quantity: 0,
      price: 125.0,
      rewards: {},
    },
  },
}

我的减速器正在监听一个动作,以向我的奖励对象添加奖励:

    case ADD_REWARD:
      return {
        ...state, campaign_products: {
          ...state.campaign_products,
          reward: {
            ...state.campaign_products.reward,
            rewards: {
              ...state.campaign_products.reward.rewards,
              question: action.payload
            }
          }
        }
      }

到目前为止一切顺利(尽管添加的每个对象都被命名为 "question")...它可以工作,但非常混乱。我尝试使用 immutability-helper 将上面的 reducer 替换为类似这样的东西,但是 newObh 被添加到我的状态

的根
case ADD_REWARD:
   const newObj = update(state.campaign_products.reward.rewards, { $merge: action.payload });
   return { ...state, newObj }
return { ...state, newObj }

首先,您必须了解 object shorthand 的工作原理。如果你熟悉 ES2015 之前的语法,上面的代码转化为:

return Object.assign({}, state, {
  newObj: newObj
});

请注意 newObj 如何同时成为键和值,这可能不是您想要的。

我假设提到的 immutability-helper 是这个库:https://www.npmjs.com/package/immutability-helper。根据文档,它 return 是根据第二个参数更新 属性 的状态副本。

您在深度 属性 上使用它,因此它会 return 那个深度 属性 的新值。因此,您仍然必须将它合并到 state 中,因此您必须保留您标记为混乱的方法。

你想要的是:

const nextState = update(state, {
  $merge: {
    campaign_products: {
      reward: {
        rewards: action.payload
      }
    }
  }
});

return nextState;

注意第一个参数是当前 state 对象,而 $merge 对象是要更新 属性 的整个对象结构。 update 的 return 值是 state,更新值基于第二个参数,即下一个状态。

旁注:正如您所发现的,使用深度状态结构很困难。我建议你研究 normalizing the state shape. If applicable, you can also split the reducers 只负责部分状态的子树,因此状态更新较小。