首页 > 解决方案 > 在 UseEffect 间隔后反应 useState 不存储新值

问题描述

我想"jokes"在 5 秒后每次运行间隔(进行 get 调用)时存储和控制台记录一个新值。但是,在每个间隔之后,该值不会呈现任何内容。我不确定笑话是否被调用和捕获,因为它打印为JOKE: []. 我的最终目标是使用"joke"状态创建逻辑。

如果您想自己测试,https://codesandbox.io/s/asynchronous-test-mp2fq?file=/AutoComplete.js

  const [joke, setJoke] = React.useState([]);

  React.useEffect(() => {
    const interval = setInterval(() => {
      axios.get("https://api.chucknorris.io/jokes/random").then((res) => {
        setJoke(res.data.value);
        console.log("JOKE: ", joke); // <- Doesn't print every time it is called.
      });

      console.log("Every 5 seconds");
    }, 5000);

    if (joke.length !== 0) {
      clearInterval(interval);
      console.log("Returns True");
    }

    return () => clearInterval(interval);
  }, []);

在此处输入图像描述

标签: javascriptreactjsreact-hooksstate

解决方案


你的setJoke电话确实有效。问题是console.log紧随其后被调用setJoke。正如这个问题的答案中提到的,setState是异步的。你可以在React 文档中找到这个问题的解释:

对 setState 的调用是异步的 - 不要依赖 this.state 在调用 setState 后立即反映新值。如果您需要根据当前状态计算值,请传递更新程序函数而不是对象(有关详细信息,请参见下文)。

joke通过将变量添加到 JSX 中,您可以看到该变量每 5 秒更改一次:

return (
    <>
    {JSON.stringify(joke)}
      <Autocomplete
        sx={{ width: 300 }}
        open={open}
        onOpen={() => {
          setOpen(true);
        }}
    ...

推荐阅读