React - React 应用程序中闭包的影响

我偶然发现了一个对我来说非常奇怪的问题,但很可能很容易解释。


演示

让我们假设以下 React 组件


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

export default function App() {

  const [test, setTest] = useState();


  const doSomething = () => {

    // TODO: Why does this returns the inital state value? Hoisting?

    console.log(test);

  };

  const doSomethingWithCallback = useCallback(doSomething, [test]);


  useEffect(() => {

    setTest("asas");


    window.setTimeout(() => doSomething(), 2000);

    document.addEventListener("click", doSomethingWithCallback);


    return () => {

      document.removeEventListener("click", doSomethingWithCallback);

    };

  }, [doSomethingWithCallback]);


  return (

    <div className="App">

      <h1>Click anywhere</h1>

    </div>

  );

}

(参见CodeSandbox)


问题

看一下TODO代码中的注释。


为什么控制台会记录最初设置的doSomething状态,即回调变体在调用时返回“真实”当前状态?testundefined


这是 React 正在做的某种提升或性能优化吗?


天涯尽头无女友
浏览 94回答 1
1回答

拉莫斯之舞

这和吊装没有太大关系。setTest正在导致重新渲染,这将导致useCallback评估它的回调,因为它的依赖项发生了变化。解释为什么另一个函数调用返回初始值有点神秘,但我认为这与您注册调用时的 test 值有关setTimeout。AnysetState是异步的,如果您设置状态然后同步尝试立即引用状态,则不能保证状态中的值与您期望的值一致。相反,它很可能不会,我没有完全了解,但我相信在同步工作队列完全为空之前或多或少不会完成任何异步工作。至于你的实际问题,“国家价值观是否被提升?”&nbsp;是的,就像 Javascript 中的所有值一样。然而,反应状态钩子值略有不同,因为它们的执行顺序在渲染之间必须始终相同,因此您必须至少保持那么多(即可能不存在条件钩子实例化)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript