繁体   English   中英

使用immer时如何更新reducer中的状态(初始状态)对象?

[英]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 教程:

https://redux.js.org/tutorials/index

您在初始状态对象中创建了一个有效负载对象,因此使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM