【问题标题】:my "useInterval" can't let the timer count properly我的“useInterval”不能让计时器正确计数
【发布时间】:2021-02-26 07:25:41
【问题描述】:

我想做一个计时器。 我的代码是

export default function Test() {
    const [count, setCount] = useState(0)
    
    function CountUp() {
        setCount(count + 1);
    }
    useInterval(() => {
        CountUp();
    }, 1000, count)

    return (
        <div>
            {count}
        </div>
    )
}

这里是useInterval

function useInterval(callback, delay) {
     const ref = useRef()
     useEffect(() => {
         ref.current = callback;
     })
     useEffect(() => {
         const timerId = setInterval(ref.current, delay); 
         return () => {
             clearInterval(timerId);
         }
     }, [delay])
 }


const timerId = setInterval(()=>{ ref.current() }, delay);

这些代码不起作用。 count 只增加了一次。

但如果我将代码const timerId = setInterval(ref.current, delay); 更改为const timerId = setInterval(() =&gt; { ref.current() }, delay);

有效! 我不明白为什么我写的代码是错误的。 你能告诉我为什么吗?

【问题讨论】:

  • 为什么你认为这是错误的?当您调试时,它是如何失败的?它与您的“正确代码”有何不同?请提供有关问题的详细信息。

标签: javascript reactjs react-hooks


【解决方案1】:

晚上好,我想它可能与javascript参考系统有关。

const timerId = setInterval(() => ref.current(), delay);

会更好;)

简而言之,当你写喜欢时

const timerId = setInterval(ref.current, delay)

您将对属性的引用传递给 ref.current 并在成功执行后,您的 ref.current 删除他对属性的引用。我可以建议你使用闭包。 () => ref.current(),它可以保证你永远存在什么引用。

【讨论】:

    【解决方案2】:

    你想给 useEffect 一个空数组作为第二个参数,这样函数在初始渲染后只运行一次。

    由于闭包的工作原理,这将使计数器变量始终引用初始值。您可以使用 setCounter 的函数版本来始终获取正确的值。

    例子

    const { useState, useEffect } = React;
    
    function App() {
      const [counter, setCounter] = useState(0);
    
      useEffect(() => {
        const interval = setInterval(() => {
          setCounter(counter => counter + 1);
        }, 1000);
    
        return () => {
          clearInterval(interval);
        };
      }, []);
    
      return <h1>{counter}</h1>;
    };
    
    ReactDOM.render(
      <App />,
      document.getElementById('root')
    );
    
    <script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
    
    <div id="root"></div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      • 1970-01-01
      • 2018-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多