反应状态更新不适用于 setState

React state update not working with setState

好吧,就这么简单

我在一系列问题中有一系列答案。 用户可以选择 select 多个答案。

当答案是 selected 时,文本应更改为 selected,如果未 selected,则文本应更改为未 selected。

这些是我尝试更新状态的步骤

第 1 步使用地图

setTestInfo((state) => {
    const allStateQuestions = state.info.questions;

    const currentQuestion = allStateQuestions.filter(
      (question) => question.id === questionId
    )[0];

    const allAnswersMap = currentQuestion.answers.map((answer) =>
      answer.id === answerId
        ? (() => {
            answer.is_chosen = !answer.is_chosen;
            return answer;
          })()
        : answer
    );
    currentQuestion.answers = allAnswersMap;

    return {
      ...state,
      info: {
        ...state.info,
        questions: allStateQuestions,
      },
    };
  });

第 2 步使用查找

setTestInfo((state) => {
    const allStateQuestions = state.info.questions;

    const currentQuestion = allStateQuestions.filter(
      (question) => question.id === questionId
    )[0];

    const currentAnswer = currentQuestion.answers.find(
      (answer) => answer.id === parseInt(answerId)
    );
     
    currentAnswer.is_chosen = !currentAnswer.is_chosen;

    // i even went to the extend of reassigning it yet it doesn't work
    currentQuestion.answers.filter((answer) => answer.id === answerId)[0] =
      currentAnswer;

    return {
      ...state,
      info: {
        ...state.info,

        questions: allStateQuestions,
      },
    };
  });

使用上面的示例逻辑后,none 似乎有效 提前致谢

问题

在这两种情况下,您都在改变状态。我将介绍第一个片段。

setTestInfo((state) => {
  const allStateQuestions = state.info.questions; // <-- reference to state

  const currentQuestion = allStateQuestions.filter( // <-- reference to state
    (question) => question.id === questionId
  )[0];

  const allAnswersMap = currentQuestion.answers.map((answer) =>
    answer.id === answerId
      ? (() => {
          answer.is_chosen = !answer.is_chosen; // <-- state mutation!!
          return answer;
        })()
      : answer
  );
  currentQuestion.answers = allAnswersMap; // <-- state mutation!!

  return {
    ...state,
    info: {
      ...state.info,
      questions: allStateQuestions, // <-- saved reference back into state
    },
  };
});

state.info.questions 状态的 currentQuestion.answers 对象发生了变异,并且 state.info.questions 数组引用从未改变,因此 React 不会将其“视为”更新并且不会触发重新渲染。

解决方案

应用不可变更新模式。您必须将所有更新浅复制到 new 数组和对象引用中。

setTestInfo((state) => {
  return {
    ...state,
    info: {
      ...state.info,
      // new questions array
      questions: state.info.questions.map(question => question.id === questionId
        ? { // new question object
          ...question,
          // new answers array
          answers: question.answers.map(answer => answer.id === answerId
            ? { // new answer object
              ...answer,
              is_chosen: !answer.is_chosen,
            }
            : answer
          ),
        }
        : question
      ),
    },
  };
});