这里的 useRef 内部发生了啥?

Posted

技术标签:

【中文标题】这里的 useRef 内部发生了啥?【英文标题】:What is Happening inside the useRef here?这里的 useRef 内部发生了什么? 【发布时间】:2021-04-28 15:40:42 【问题描述】:

我正在使用 react.js 创建一个 Slider。 我需要在这里自动调用 nextSlide 函数。所以,我使用了 useEffect 钩子。 我有这样的代码

const [current, setCurrent] = useState(0);
  const length = slides.length;
  const timeout = useRef(null);
  useEffect(() => 
    const nextSlide = () =>
      setCurrent((prevState) => (prevState === length - 1 ? 0 : prevState + 1));
    timeout.current = setTimeout(nextSlide, 3000);
    return function () 
      if (timeout.current) 
        clearTimeout(timeout.current);
      
    ;
  , [current, length]);

但我对里面发生的事情感到困惑。 useRef 钩子如何在这种情况下提供帮助?

提前致谢

【问题讨论】:

它没有。这是不必要的。 【参考方案1】:

useRef 在重新渲染时返回相同的对象,因此通常它可以用于存储值,以便可以在回调中检索并始终反映最新值。现在在您的情况下,这不是必需的,因为您想引用 effects cleanup 内部的计时器,并且因为这是 effect 的内部函数,所以您可以参考它的变量:

 useEffect(() => 
   // ...
   const timer = setTimeout(nextSlide, 3000);

   return function () 
    clearTimeout(timer);
   ;
 , [length]);

【讨论】:

【参考方案2】:

考虑js代码

function foo()
    let x = 1;
    console.log(x++);
 

foo();
foo();

这里的输出是1 1而不是1 2,因为每次调用它都会创建一个新的范围,其中x的值最初设置为1。在一个范围内修改一个变量不会影响另一个。

React 函数式组件是简单的 javascript 函数。 React 通过再次调用函数来响应函数组件中的状态变化。

如果您使用以下语法而不是 useRef

const MyComponent = ()=>
     const [current, setCurrent] = useState(0);
     let timeout = null;
     ...

每当您调用 setCurrent 时,timeout 的值都会重置为 null。因为 react 会再次调用函数来获取更新后的输出。因此该函数将失去对计时器的控制并显示出意外的行为。

useRef() 不会返回变量,而是对函数范围之外的变量/内存位置的引用。因此,对于每次调用,函数变量都不会重新创建,而是使用它的引用。

对于const timeout = useRef(null) timeout 是参考,它的当前值可以使用`ti获得

替代解决方案

在组件外部声明超时变量也是一种解决方案。

let timeout = null;
const MyComponent = ()=>
     const [current, setCurrent] = useState(0);
     ...

【讨论】:

以上是关于这里的 useRef 内部发生了啥?的主要内容,如果未能解决你的问题,请参考以下文章

Maven Polyglot 发生了啥?

“使用高效的 CSS 选择器”规则发生了啥?

在 pytorch 的嵌入层中“究竟”发生了啥?

将 Apollo Server NODE_ENV 设置为“生产”模式实际上(内部)做了啥?

这里发生了啥?核心数据/iCloud

C++ 这里到底发生了啥? [关闭]