javascript - 为什么 React 状态没有在函数内部更新?

标签 javascript reactjs react-hooks

我有一个渲染带有对象的表格的组件。该组件显示一个按钮,按下该按钮会向父级发送特定对象。父级必须将其设置为显示一些图形内容的状态。渲染工作正常,我不明白的是为什么在正确设置状态后我得到了过时的值。 这不是竞争条件,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>;
}

Edit react update state

即使有像 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/

相关文章:

javascript - 我的 index.js 中没有任何 React 渲染

javascript - 通过 state.value ReactJS 将 textarea 值复制到新组件

javascript - IntersectionObserverAPI 当所有元素都不可见时返回默认状态

reactjs - React useEffect 钩子(Hook)依赖于第二个效果

javascript - 过渡动画,高cpu?

javascript - 将德国日期转换为 ISO 日期

javascript - 如果我使用 $.mobile.changePage() 则页面无法正确显示

arrays - 如果对象或数组中不存在键,如何停止React应用程序失败?

javascript - JSLint 无法识别 getElementById

reactjs - 正在重置的状态