【问题标题】:Why is the setstate not updating the value in ReactJs?为什么 setstate 不更新 ReactJs 中的值?
【发布时间】:2021-08-11 13:34:18
【问题描述】:

我在我的应用程序中使用 reactjs。 currid_s 最初设置为值 -1 .. 稍后单击按钮后将其设置为 2,但计时器不会在控制台中显示更新的值。为什么? 这是代码

 
import React, { useState, useEffect } from "react";

export default function App() {
  const [currid_s, setcurrid_s] = React.useState(-1);
  const handless = () => {
    console.log("yess");
    setcurrid_s(2);
  };

  useEffect(() => {
    console.log(currid_s, "yes");
    getPosts();

    const interval = setInterval(() => {
      getPosts();
    }, 2000);

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

  // const all_pooo=()=>{
  //   console.log(curr,"dddd")
  // }
  const getPosts = async () => {
    console.log(currid_s);
  };
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <button onClick={handless}>gggg</button>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

这里是代码沙箱的链接 https://codesandbox.io/embed/beautiful-ardinghelli-dg1r4?file=/src/App.js&codemirror=1

【问题讨论】:

  • 时间间隔的回调函数对设置定时器时间间隔时有效的currid_s 的值有一个闭包。每当currid_s 更新时,您都需要设置一个新的时间间隔。您可以通过在 useEffect 挂钩的依赖数组中添加 currid_s 来做到这一点。
  • @Yousaf 但间隔如何影响 currid_s 值?
  • 你能在密码框里改一下@Yousaf吗?
  • @TusharShahi 你是什么意思? setInterval 没有改变它的值;它只是调用一个函数,即getPosts,记录currid_s 的值。

标签: javascript reactjs react-hooks state


【解决方案1】:

您可以将 currid_s 从 useState() 更改为 useRef(),以便可以从 setInterval 回调捕获的闭包中访问其值:

const { useRef, useEffect } = React;

function App() {
  const currid_s = useRef(-1);
  const handless = () => {
    currid_s.current = 2;
  };

  useEffect(() => {
    const getPosts = () => {
      console.log(currid_s.current);
    };

    getPosts();

    const interval = setInterval(() => {
      getPosts();
    }, 2000);

    return () => {
      clearInterval(interval);
    };
  }, []);
  
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <button onClick={handless}>Click me</button>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>

【讨论】:

    【解决方案2】:

    您无法在 setInterval 中获取新的状态值,因为您在区间回调函数中存储了旧版本的 getPosts。

    当currid_s 更新时会发生什么情况,您的 App 组件重新呈现,并且包含新值的新 getPosts 函数被初始化。但是,setInterval 回调函数存储对包含旧值的旧 getPosts 函数的引用。这个旧的 getPosts 函数将打印在安装 App 组件时分配的旧 currid_s 值的副本。 Javascript 不支持对原语的引用,这就是为什么您的旧 getPosts 函数没有新值。

    如果您想在更新时打印您的currid_s,只需执行以下操作:

    useEffect(() => {
      console.log(currid_s)
    }, [currid_s])
    

    【讨论】:

    • 我的网站上有很多反应钩子。我应该在依赖项中添加所有这些吗?
    猜你喜欢
    • 2016-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2015-12-17
    • 2021-01-26
    • 2021-12-06
    相关资源
    最近更新 更多