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.assign
或 spread operator
语法来实现您想要的,您不需要同时使用
case types.LOAD_PROFILE_SUCCESS:
return Object.assign([], state, action.profile)
case types.LOAD_PROFILE_SUCCESS:
return [...state, action.profile]
但是 React 文档建议您在 Object.assign 上使用 Spread 语法,请参阅此 post:
我有一个 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.assign
或 spread operator
语法来实现您想要的,您不需要同时使用
case types.LOAD_PROFILE_SUCCESS:
return Object.assign([], state, action.profile)
case types.LOAD_PROFILE_SUCCESS:
return [...state, action.profile]
但是 React 文档建议您在 Object.assign 上使用 Spread 语法,请参阅此 post: