在 React 对象更新中但不将更新的对象传递给下一个函数

In React object updates but does not pass updated object to next function

我正在使用 React 并拥有以下对象:

const [records, setRecords] = useState(
    [
      {id: 1, correct: false},
      {id: 2, correct: false},
      {id: 3, correct: false},
      {id: 4, correct: false},
      {id: 5, correct: false}
    ]);

要更新对象,我有以下内容:

const onCorrectAnswerHandler = (id, correct) => {
    setRecords(
      records.map((record) => {
        if (record.id === id) {
          return { id: id, correct: true };
        } else {
          return record;
        }
      })
    );
  }

这是问题所在:

我想 运行 另一个函数 isComplete 在它之后但在 Handler 函数中,它使用更改后的 records 对象,但它似乎使用原始未更改的 'records' 对象(console.log 确认)。

例如

const onCorrectAnswerHandler = (id, correct) => {
    setRecords(
      records.map((record) => {
        if (record.id === id) {
          return { id: id, correct: true };
        } else {
          return record;
        }
      })
    );
    isComplete(records);
  }

Console.log(records) 证实了这一点。为什么它不使用更新后的 records,因为 isComplete 函数 运行 更新后,我怎样才能让它这样做?

您可以修改上面的 onCorrectAnswerHandler 函数,将更新后的记录保存在临时变量中,用于更新状态和调用 isComplete func

const onCorrectAnswerHandler = (id, correct) => {
    let _records = records.map((record) => {
        if (record.id === id) {
            return {
                id: id,
                correct: true
            };
        } else {
            return record;
        }
    })
    setRecords(_records);
    isComplete(_records);
}

请试试这个。

  const onCorrectAnswerHandler = (id) => {
    records.forEach(r =>{
      if(r.id == id)  r.correct=true; 
    });
     setRecords([...records]);
  }

这是因为 setState 实际上不是同步的。调用 setState 时,状态值不会立即更新,而是在下一个渲染周期更新。这是因为 React 做了一些幕后工作来优化 re-renders。

有多种方法可以解决这个问题,其中一种方法是:

如果您需要收听 state 对 运行 一些逻辑的更新,您可以使用 useEffect 挂钩。

useEffect(() => {
  isComplete(records)
}, [records])

这个钩子非常简单。第一个参数是 function。如果依赖数组中的一个变量更新,这个 function 将 运行 每次。在这种情况下,它会 运行 每次 records 更新。

尝试重命名函数,因为 React 认为对象没有变化,当您在状态中使用数组或对象时也是如此。尝试通过将它们存储在新变量中来复制它们。

setRecords(
  const newRecords = records.map((record) => {
    if (record.id === id) {
        return { id: id, correct: true };
      } else {
        return record;
      }
    })
   //seting this now triggers an update
   setRecords(newRecords);
);

然后根据 React 文档,最好使用生命周期方法监听更改,而不是在更改后立即设置状态,因为 useState 是异步的。

所以使用useEffect来监听设置完成的变化

useEffect(() => {
  isComplete(records)
}, [records])

希望对您有所帮助?