在 Redux 中删除项目而不改变状态

Remove Item Without Mutating State in Redux

我尝试的第一件事是:

const initialState = {
  items: {},
  showCart: false,
  showCheckout: false,
  userID: null
};

export default function reducer(state=Immutable.fromJS(initialState), action) {
  case 'REMOVE_FROM_CART':
    return state.deleteIn(['items', String(action.id)]);
}

当控制台记录上面的 deleteIn 时,它实际上确实从 Map 中正确删除了该项目。但是,该应用程序不会再次重新呈现,因为我假设我正在改变状态(?)。 (调用了 mapStateToProps,但没有新状态)。

接下来我尝试了这个:

case 'REMOVE_FROM_CART':
  const removed = state.deleteIn(['items', String(action.id)]);
  const removeItemState = {
    ...state,
    items: { removed } 
  }
  return state.mergeDeep(removeItemState);

但我只是将已删除的项目再次添加到项目中,创建了一个副本。

我该如何处理?

您是否尝试过在达到 deeply cloned 状态后删除该项目?

case 'REMOVE_FROM_CART':
    const removeItemState = {
        ...state
        items: {
            ...state.items
        }
    };

    delete removeItemState.items[String(action.id)];

    return removeItemState;

减少怎么样?

case 'REMOVE_FROM_CART':
  return {
    ...state,
    items: Object.keys(state.items).reduce((acc, curr) => {
      if (curr !== action.id) acc[curr] = state.items[curr];
      return acc;
    }, {})
  };

发布更多代码(例如我的 reducer 设置)可能 有更多帮助,但实际情况如下:

首先,这段代码是从状态中删除项目的正确方法。

return state.deleteIn(['items', String(action.id)]);

但是,因为我使用的是 immutable 库而不是 redux-immutable 用于我的 combineReducers,所以我的状态没有得到正确处理。这让我可以做像 state.cart.items(在 mapStateToProps 中)这样的事情,而实际上我应该使用 state.getIn(['cart', 'items'])

改变那个神奇地使删除工作。

感谢 Reactiflux Immutable Slack 频道中的@jslatts 帮助解决这个问题!