如何在替换数组中的值后立即更新反应状态

How to instantly update react state after replacing the value from array

我有一个函数可以获取用户输入并在相同的键已经可用时更新数组。借助这个 article

这是它的样子;

  const handleClickYes = (question) => {
    // find if question is in the data array
    const hasQuestion = data.find(({ parentId }) => question.id === parentId)
    
    const indexOfQuestion = data.indexOf(hasQuestion)
    
    if (hasQuestion) {
      // update the value with specific selected index in the array. 
      data[indexOfQuestion] = { question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }
    } else {
      setData((data) => data.concat({ question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }))
    }
    localStorage.setItem('deviceReport', JSON.stringify(data))
  }

我正在使用 localStorage 来保存状态

  const deviceReport = localStorage.getItem('deviceReport') ? JSON.parse(localStorage.getItem('deviceReport')) : []
  const [data, setData] = useState(deviceReport)

这里的问题是如果我使用 setData 那么它会立即更新但在替换数组时 在这部分

data[indexOfQuestion] = { question: question.if_yes, parentId: question.id, userChoice: 'YES', child: [] }

它不会更新 JSX 部分的映射数据。我如何配置它以更新它发生在 setState 中。 ?或者任何其他更新阵列的更好选择。

您没有在 if 块的前半部分调用 setState()。另外,。制作一个可变副本,如下所示:

const handleClickYes = (question) => {
  // find if question is in the data array
  const hasQuestion = data.find(({ parentId }) => question.id === parentId);

  const indexOfQuestion = data.indexOf(hasQuestion);

  // copy data to mutable object
  let newData = [...data];
  if (hasQuestion) {
    // update the value with specific selected index in the array.
    newData[indexOfQuestion] = {
      question: question.if_yes,
      parentId: question.id,
      userChoice: "YES",
      child: [],
    };
  } else {
    //   concat existing data with a new question
    newData = [
      ...newData,
      {
        question: question.if_yes,
        parentId: question.id,
        userChoice: "YES",
        child: [],
      },
    ];
  }
  localStorage.setItem("deviceReport", JSON.stringify(newData));
  setData(newData);
};