React Redux reducer 正在覆盖值 LOAD_SUCCESS?

React Redux reducer is overwriting values LOAD_SUCCESS?

我有一个 profilesReducer,我想用它在我的 redux 存储中存储 1 个或多个用户配置文件。以 Twitter 为例,它需要存储我的个人资料以及其他个人资料。

这是我的 profilesReducer.js:

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

const initialState = []

export default function profilesReducer(state = initialState, action) {
  switch (action.type) {
    case types.LOAD_PROFILE_SUCCESS:
      return [Object.assign({}, action.profile)]
    case types.UPDATE_PROFILE_SUCCESS:
      return [
        ...state.filter(profile => profile.id !== action.profile.id),
        Object.assign({}, action.profile)
      ]
    default:
      return state;
  }
}

问题是 LOAD 正在接收多个配置文件(由 profile.id 区分)但正在覆盖商店中的现有配置文件而不是 appending/updating。

我需要 LOAD_PROFILE 才能在商店中允许超过 1 个用户的个人资料。有什么建议吗?

编辑

我已经更改了我的解决方案,它包括一种更新数组的方法。

这是一个CodeSandbox to test: https://codesandbox.io/s/zk9r6k1z4p

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

const initialState = []

export default function profilesReducer(state = initialState, action) {
  switch (action.type) {
    case types.LOAD_PROFILE_SUCCESS:
      return [...state, action.profile]
    case types.UPDATE_PROFILE_SUCCESS:
      return state.map( (profile) => {
        if(profile.id !== action.profile.id) {
          return profile;
        }

        return {
          ...profile,
          ...action.profile
        };    
     });
    default:
      return state;
  }
}

很确定您的代码需要更改为此。

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

const initialState = []

export default function profilesReducer(state = initialState, action) {
  switch (action.type) {
    case types.LOAD_PROFILE_SUCCESS:
      return [...Object.assign({}, action.profile)]
    case types.UPDATE_PROFILE_SUCCESS:
      return [
        ...state.filter(profile => profile.id !== action.profile.id),
        Object.assign({}, action.profile)
      ]
    default:
      return state;
  }
}

按照您的方式,您只是在 action.profile 中返回一个包含此项目的数组,但您需要将您的项目添加到已有其他项目的数组中。您也不能简单地推送,因为那样会改变数组。这行就是您需要更改的全部内容。

return [Object.assign({}, action.profile)] 不追加

return [...Object.assign({}, action.profile)] 确实附加并且不变异。

传播现有状态并在末尾添加新配置文件:

case types.LOAD_PROFILE_SUCCESS:
  return [...state, action.profile]

Object.assing({}, action.profile) 是不必要的,因为它在这里所做的只是将 action.profile 复制到一个新的空对象 {} 和 returns 它。

您可以使用 Object.assignspread operator 语法来实现您想要的,您不需要同时使用

Object.assign,

case types.LOAD_PROFILE_SUCCESS:
  return Object.assign([], state, action.profile)

Spread operator syntax

case types.LOAD_PROFILE_SUCCESS:
  return [...state, action.profile]

但是 React 文档建议您在 Object.assign 上使用 Spread 语法,请参阅此 post: