簡體   English   中英

React state 更新不適用於 setState

[英]React state update not working with setState

好的,這很簡單

我在一系列問題中有一系列答案。 用戶可以選擇 select 多個答案。

選擇答案后,如果未選擇文本,則文本應更改為已選擇和未選擇。

這些是我嘗試更新 state 的步驟

步驟 1 使用 map

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,
      },
    };
  });

在使用上面的示例邏輯之后,它們似乎都不起作用提前謝謝

問題

在這兩種情況下,您都在改變 state。 我將介紹第一個片段。

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
    },
  };
});

The currentQuestion.answers object of the state.info.questions state was mutated and the state.info.questions array reference never changed so React isn't "seeing" this as an update and isn't triggering a rerender.

解決方案

應用不可變更新模式。 您必須將所有更新淺復制到數組和 object 引用中。

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
      ),
    },
  };
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM