在redux reducer中修改数组中特定项的状态

在redux reducer中修改数组中特定项的状态,redux,reactjs,typescript,react-redux,state,Redux,Reactjs,Typescript,React Redux,State,我不能完全把我的头放在我的样板上。我查找了一些常见的模式,但问题是,所有这些模式都只是将其推向末尾,而不是特定的索引 在我进入实际代码之前,以下是状态的结构的外观,以便更好地发挥想象力(伪代码): 现在我的减速机是这样的: const reducer = createReducer({//...}, { [actionAddQuestionOption.type]: (state, action) => ({ ...state, quizEditor: [...s

我不能完全把我的头放在我的样板上。我查找了一些常见的模式,但问题是,所有这些模式都只是将其推向末尾,而不是特定的索引

在我进入实际代码之前,以下是状态的结构的外观,以便更好地发挥想象力(伪代码):

现在我的减速机是这样的:

const reducer = createReducer({//...}, {
   [actionAddQuestionOption.type]: (state, action) => ({
     ...state,
     quizEditor: [...state.quizEditor][action.payload.questionId].questionOptions.push({
        id: action.payload.id,
        optionText: action.payload.optionText,
        isValid: action.payload.isValid,
     })
   })
}
这将导致以下怪物类型错误:

但是我很确定我在错误地访问对象数组中的数组

quizEditor: [...state.quizEditor][action.payload.questionId].questionOptions

有人知道访问它的正确方式吗?非常感谢

数组的
push
方法返回数组的新长度,而不是数组本身。您可以做的只是将新对象
concat
添加到数组中,该数组将返回带有新问题选项的新数组

[...state.quizEditor][action.payload.questionId].questionOptions.concat({
        id: action.payload.id,
        optionText: action.payload.optionText,
        isValid: action.payload.isValid,
     })
此外,我们必须使用新数组仅修改状态中的该属性:

const reducer = createReducer({
  //...}, {
  [actionAddQuestionOption.type]: (state, action) => {
    const quizEditor = [...state.quizEditor];
    quizEditor[action.payload.questionId].questionOptions = quizEditor[
      action.payload.questionId
    ].questionOptions.concat({
      id: action.payload.id,
      optionText: action.payload.optionText,
      isValid: action.payload.isValid
    });

    return {
      ...state,
      quizEditor
    };
  }
});
由于redux toolkit中的immer,我们可以使其更具可读性:

const reducer = createReducer({
  //...}, {
  [actionAddQuestionOption.type]: (state, action) => {
    const question = state.quizEditor[action.payload.questionId];
    question.questionOptions = [
      ...question.questionOptions,
      {
        id: action.payload.id,
        optionText: action.payload.optionText,
        isValid: action.payload.isValid
      }
    ];

    return state;
  }
});

Array
push
方法返回数组的新长度,而不是数组本身。您可以做的只是将新对象
concat
添加到数组中,该数组将返回带有新问题选项的新数组

[...state.quizEditor][action.payload.questionId].questionOptions.concat({
        id: action.payload.id,
        optionText: action.payload.optionText,
        isValid: action.payload.isValid,
     })
此外,我们必须使用新数组仅修改状态中的该属性:

const reducer = createReducer({
  //...}, {
  [actionAddQuestionOption.type]: (state, action) => {
    const quizEditor = [...state.quizEditor];
    quizEditor[action.payload.questionId].questionOptions = quizEditor[
      action.payload.questionId
    ].questionOptions.concat({
      id: action.payload.id,
      optionText: action.payload.optionText,
      isValid: action.payload.isValid
    });

    return {
      ...state,
      quizEditor
    };
  }
});
由于redux toolkit中的immer,我们可以使其更具可读性:

const reducer = createReducer({
  //...}, {
  [actionAddQuestionOption.type]: (state, action) => {
    const question = state.quizEditor[action.payload.questionId];
    question.questionOptions = [
      ...question.questionOptions,
      {
        id: action.payload.id,
        optionText: action.payload.optionText,
        isValid: action.payload.isValid
      }
    ];

    return state;
  }
});
由于您使用的是内置的,您可以直接改变状态,它将在内部将其转换为不可变的更新

const reducer=createReducer({
[actionAddQuestionOption.type]:(状态,{payload:{questionId,{option})=>{
const question=state.questionquizEditor(question=>question.id===questionId)
问题。问题选项。推送(选项)
}
})
使其成为不可变更新的方法如下

const reducer=createReducer({
[actionAddQuestionOption.type]:(状态,{payload:{questionId,{option})=>({
……国家,
quizEditor:state.quizEditor.map(问题=>
(问题id==问题id
? {
……问题,
questionOptions:[…question.questionOptions,option],
}
:问题(,
}),
})
由于您使用的是内置的,您可以直接改变状态,它将在内部将其转换为不可变的更新

const reducer=createReducer({
[actionAddQuestionOption.type]:(状态,{payload:{questionId,{option})=>{
const question=state.questionquizEditor(question=>question.id===questionId)
问题。问题选项。推送(选项)
}
})
使其成为不可变更新的方法如下

const reducer=createReducer({
[actionAddQuestionOption.type]:(状态,{payload:{questionId,{option})=>({
……国家,
quizEditor:state.quizEditor.map(问题=>
(问题id==问题id
? {
……问题,
questionOptions:[…question.questionOptions,option],
}
:问题(,
}),
})

是的,我不适合俯瞰。实际上我的问题已经修改了一半。不管怎样,遗憾的是,即使使用您的解决方案,我仍然会遇到与我的原始问题中提到的类似类型的错误是的,我现在知道问题了!给我一点时间重写解决方案:)这将返回修改后的状态。我想最简单的方法应该是将阵列拼接到
optionId
并展开
…直到拼接,新项目,…拼接后,
?它将返回修改状态。多亏了伊默,我们可以做到这一点,并将得到一个不变的结果。查看他们的更多信息。是的,这是我不好的忽视。实际上我的问题已经修改了一半。不管怎样,遗憾的是,即使使用您的解决方案,我仍然会遇到与我的原始问题中提到的类似类型的错误是的,我现在知道问题了!给我一点时间重写解决方案:)这将返回修改后的状态。我想最简单的方法应该是将阵列拼接到
optionId
并展开
…直到拼接,新项目,…拼接后,
?它将返回修改状态。多亏了伊默,我们可以做到这一点,并将得到一个不变的结果。查看他们的更多信息。嘿,各位,多亏了阿萨法维夫的帮助,我已经解决了这个问题,不管是哪种方式,只要把这个留在这里作为一个工作示例,以防任何人发现它有用:嘿,各位,多亏了阿萨法维夫的帮助,我已经解决了这个问题,不管是哪种方式,只要把这个留在这里作为一个工作示例,以防任何人发现它有用: