[英]How to update state ( initial State ) objects in reducer when using immer?
如果有对象有效负载的状态:
export const initialState = {
payload: {
firstName: 'Mick',
lastName: 'Andri',
phoneNumber: '651-332-5675',
electronicMailAddress: 'mandradi@lake.com',
addressLine1: '27 Crest Ave',
addressLine2: '',
cityName: 'San Jose',
stateCode: 'CA',
zipCode: '92122',
},
};
并以某种方式加载此状态,我使用 immer:
const SettingsReducer = (state = initialState, action) =>
produce(state, (draft) => {
switch (action.type) {
case actionTypes.LOAD_SETTINGS_INFO:
draft.payload = action.payload;
break;
}
});
export default SettingsReducer;
如果我们使用 JavaScript 对象和数组展开语法以通常的方式执行此操作,我们的 state reducer 可能如下所示,这只是一个示例:
draft.payload = action.payload;
case 'UPDATE_SETTINGS_INFO':
return {
...state,
payload: [...state.payload, action.payload],
};
就我而言:
我通过 react hook 表单获取所有字段并尝试更新我的状态。 我需要在不丢失整个数据的情况下更新状态。
下面的代码有效,但会从状态中删除其余数据。
case actionTypes.UPDATE_SETTINGS_INFO:
draft.payload = action.payload;
break;
我需要一次更新一半的状态。
在不丢失整个数据的情况下克隆状态的最佳方法是什么?
首先,我建议不要有state.payload
字段。 “有效负载”通常用于描述“动作对象的内容”,作为一个术语,它对于减速器中的状态确实没有意义。
其次,听起来您在这里尝试做的是将两个对象合并在一起,以便第二个中的字段覆盖第一个中的字段。 如果我们正在做一个不可变的更新(并假设state
本身是原始数据),我们可以做return {...state, ...action.payload}
。
使用 Immer,您可以直接“变异”对象:
state.a = action.payload.a;
state.b = action.payload.b;
// etc
如果您想一次更新多个字段,并且action.payload
将包含原始状态的部分或全部字段,您可以使用 Immer 执行此操作:
// Object.assign always mutates its first argument
Object.assign(state, action.payload);
最后,我特别推荐使用我们的官方 Redux Toolkit 包,它已经在其createSlice
API 中使用了 Immer:
const settingsSlice = createSlice({
name: 'settings',
initialState,
reducers: {
settingsLoaded(state, action) {
Object.assign(state, action.payload)
}
}
});
有关更多详细信息,请参阅 Redux 教程:
您在初始状态对象中创建了一个有效负载对象,因此使用markerikson 的设置,如果您更改任何设置,我相信整个有效负载对象都将被替换。 您的初始状态应该是:
export const initialState = {
firstName: 'Mick',
lastName: 'Andri',
phoneNumber: '651-332-5675',
electronicMailAddress: 'mandradi@lake.com',
addressLine1: '27 Crest Ave',
addressLine2: '',
cityName: 'San Jose',
stateCode: 'CA',
zipCode: '92122',
};
然后您应该能够使用以下方法更改该 initialState 对象中的任何单个设置:
dispatch(settingsLoaded(changedState))
并作为一个例子:
const changedState = {
cityName: 'Bozeman',
stateCode: 'MT',
zipCode: '94565',
}
如果我正确理解您的问题,它会保留您的更改以及您未更改的所有内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.