反应状态在dom中的变化,但在逻辑中没有变化

发布于 2025-02-01 17:17:10 字数 767 浏览 3 评论 0原文

在这里,我们遇到了一个奇怪的问题。我是Reactjs Newbie,并从事一个简单的计时器项目。 我的代码如下:

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

const TestTimer = () => {

    const [seconds, setSeconds] = useState(10);

    useEffect(() => {
        let timer = setInterval(() => {
            console.log(seconds);
            setSeconds(function(seconds){
                return seconds - 1;
            });
        }, 1000)
    }, []);

    return (
        <div className="timer-component text-light">
            { seconds }
        </div>
    )
}

export default TestTimer; 

问题是,在DOM中,我们可以在几秒钟内看到更改。每一秒钟,它都会下降1。

但是在控制台中,我所看到的只是相同的“ 10”。它仅打印每秒10个。

在哪里做错了?任何帮助都将受到赞赏。

我也搜索了很多问题,但是所有问题都是关于“状态正在改变,但我们对DOM没有变化”。我的反之亦然!

Here we got a strange problem. I'm a reactJs newbie and working on a simple Timer project.
my code is like below:

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

const TestTimer = () => {

    const [seconds, setSeconds] = useState(10);

    useEffect(() => {
        let timer = setInterval(() => {
            console.log(seconds);
            setSeconds(function(seconds){
                return seconds - 1;
            });
        }, 1000)
    }, []);

    return (
        <div className="timer-component text-light">
            { seconds }
        </div>
    )
}

export default TestTimer; 

The problem is, that in DOM we can see the change in seconds. every second passes, it goes down by 1.

But in the console, all I see is the same "10". It only prints 10 every seconds.

Where am doing it wrong? any help is appreciated.

Also I searched a lot about it but all problems are about "state being changed, but we have no change in DOM". Mine is completely vice versa!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最舍不得你 2025-02-08 17:17:10

因为您已经在setInterval回调中使用了console.log,实际上此回调可以访问状态的初始值,因此您可以将console.log移至状态更新函数中并获得这样的预期结果:

const TestTimer = () => {

    const [seconds, setSeconds] = React.useState(10);

    React.useEffect(() => {
        let timer = setInterval(() => {
            setSeconds(function(seconds){
                console.log(seconds);
                return seconds - 1;
            });
        }, 1000)
    }, []);

    return (
        <div className="timer-component text-light">
            { seconds }
        </div>
    )
}

ReactDOM.render(<TestTimer/>, document.getElementById("root"))
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>

<div id="root"></div>

Because you have used console.log inside setInterval callback, and actually this callback has access to the initial value of state, you can move your console.log inside the state updater function and get the expected result, like this:

const TestTimer = () => {

    const [seconds, setSeconds] = React.useState(10);

    React.useEffect(() => {
        let timer = setInterval(() => {
            setSeconds(function(seconds){
                console.log(seconds);
                return seconds - 1;
            });
        }, 1000)
    }, []);

    return (
        <div className="timer-component text-light">
            { seconds }
        </div>
    )
}

ReactDOM.render(<TestTimer/>, document.getElementById("root"))
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>

<div id="root"></div>

深者入戏 2025-02-08 17:17:10

有几个问题:

  1. 根据您的问题,您在setInterval回调中调用台(),但在状态设置器函数之外。因此,这仅访问您的默认值,然后在每个返回时重印。

     让timer = setInterval(()=&gt; {
          setSeconds(函数(秒){
            console.log(秒); &lt; -------在州设定器中的控制器
              返回秒-1;
          });
      },1000)
     
  2. 您的代码每次调用使用效果时都会按-2更新。这是因为您没有清理使用效率调用。最好习惯使用使用计时器在使用效果中的计时器,否则您会遇到此类问题,这是一个好习惯。阅读有关使用效果


这是您的示例清理功能和预期的结果

    useEffect(() => {
      let timer = setInterval(() => {
          setSeconds(function(seconds){
            console.log(seconds);
              return seconds - 1;
          });
      }, 1000)
      return () => clearInterval(timer) <----- Cleanup function
    },[]); 

There's a couple issues:

  1. Per your question, you're calling your console.log() inside the setInterval callback but outside of your state setter function. So this is only accessing your default value and then reprinting on every return.

      let timer = setInterval(() => {
          setSeconds(function(seconds){
            console.log(seconds); <------- Console here within state setter
              return seconds - 1;
          });
      }, 1000)
    
  2. Your code is updating by -2 every time useEffect is called. This is because you aren't cleaning up your useEffect call. It's good practice to always cleanup a function utilizing a timer within a useEffect or else you run into problems like so. Read more about useEffect https://reactjs.org/docs/hooks-reference.html#useeffect

Here's your example with a cleanup function and your intended results

    useEffect(() => {
      let timer = setInterval(() => {
          setSeconds(function(seconds){
            console.log(seconds);
              return seconds - 1;
          });
      }, 1000)
      return () => clearInterval(timer) <----- Cleanup function
    },[]); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文