我有一个渲染带有对象的表格的组件。该组件显示一个按钮,按下该按钮会向父级发送特定对象。父级必须将其设置为显示一些图形内容的状态。渲染工作正常,我不明白的是为什么在正确设置状态后我得到了过时的值。 这不是竞争条件,React 只是忽略变量的更新值,即使它正确地重新渲染了组件。
一个最小的例子:
import { useState } from "react";
import { SomeComponent } from "./SomeComponent";
export default function App() {
const [currentID, setCurrentID] = useState(null);
function getData() {
console.log("Getting data of: ", currentID); // PROBLEM: this is null
}
function setAndRetrieveData(value) {
setCurrentID(value);
// Just to show the problem and discard race conditions.
setTimeout(() => {
getData();
}, 1500);
}
return (
<div className="App">
<h1>Current ID: {currentID}</h1> {/* This works fine */}
<SomeComponent getInfoFor={setAndRetrieveData} />
</div>
);
}
某些组件:
export function SomeComponent(props) {
const randomID = 45;
return <button onClick={() => props.getInfoFor(randomID)}>Get info</button>;
}
即使有像 useStateCallback 这样的解决方案问题仍然存在。
有没有一种方法可以做到这一点,而不必使用可怕的 useEffect
阅读代码时不清楚?因为系统的逻辑是“当按下这个按钮时,发出请求获取信息”,使用钩子(Hook)useEffect
逻辑变成“当 currentID
的值更改时发出请求”,如果在某个时刻我想更改该变量的状态并执行另一个不从服务器获取数据的操作,那么我就会遇到麻烦.
提前致谢
最佳答案
我认为这是 Javascript 闭包工作方式的问题。
当您执行一个函数时,它会与与其相关的所有数据捆绑在一起,然后被执行。
问题是你这样称呼:
setTimeout(() => {
getData();
}, 1500);
内部setAndRetrieveData(value)
。
尽管 getData() 函数位于 setTimeout 内部,但它已在该时间点(而不是在其实际运行时)与其所需的信息 (currentID
) 捆绑在一起。因此,在状态更新发生之前,它会与 currentId 捆绑在一起
不幸的是,我建议使用 useEffect。这是确保避免此类问题和任何潜在竞争条件的最佳方法。希望其他人可以提供不同的方法!
关于javascript - 为什么 React 状态没有在函数内部更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72956844/