Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我们需要在React钩子中返回一个函数?_Javascript_Reactjs_Material Ui - Fatal编程技术网

Javascript 为什么我们需要在React钩子中返回一个函数?

Javascript 为什么我们需要在React钩子中返回一个函数?,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,我正在项目中使用Material UI组件,并在我的应用程序中使用AutoComplete组件 在Material UI团队的示例中,我遇到了一个自动完成Ajax数据的有趣示例: 他们正在使用React钩子从服务器获取数据: React.useEffect(() => { let active = true; if (!loading) { return undefined; } (async () => { const r

我正在项目中使用Material UI组件,并在我的应用程序中使用
AutoComplete
组件

在Material UI团队的示例中,我遇到了一个自动完成Ajax数据的有趣示例:

他们正在使用React钩子从服务器获取数据:

React.useEffect(() => {
    let active = true;

    if (!loading) {
      return undefined;
    }

    (async () => {
      const response = await fetch('https://country.register.gov.uk/records.json?page-size=5000');
      await sleep(1e3); // For demo purposes.
      const countries = await response.json();

      if (active) {
        setOptions(Object.keys(countries).map((key) => countries[key].item[0]));
      }
    })();

    return () => {
      active = false;
    };
  }, [loading]);
为什么我们在这里使用
active
变量?为什么我们返回一个函数将此变量更改为
false
?在
if语句中总是
true

提前感谢您的回答

这是一种用于避免两种情况的模式:

  • 如果包含此钩子的组件在HTTP请求完成之前已卸载,则更新状态
  • 避免比赛条件
  • useffect
    hook的回调函数返回的函数用于执行清理,如基于类的组件中的
    componentWillUnmount
    。此清理功能在组件卸载时或下次运行效果之前运行

    因此,如果在HTTP请求进行时卸载了组件,useEffect钩子的清理功能将运行,并将
    active
    设置为false。之后,无论何时HTTP请求的结果返回,状态都不会更新,因为
    active
    将为false


    请参阅react docs的一节,了解
    useEffect
    钩子的清除功能,并参阅,更好地了解通过使用
    active
    变量解决的与竞态条件相关的问题。

    useEffect
    返回的函数是一个函数。它在组件卸载时调用,通常用于取消订阅
    useffect
    中使用的事件、取消挂起的承诺等

    使用
    active
    变量确保您没有更新不再存在的对象的状态。这有点像类组件中存在的反模式

    当您尝试更新未安装组件的状态时,React将抛出警告-

    警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏

    激活
    变量可以通过以下方式防止:

    • 您的组件已加载
    • useffect
      调用一个
      async
      fetch-这需要时间
    • 现在,假设在返回响应中的服务器之前,您导航离开页面(或者执行其他一些取消装载组件的操作)
    • 这将导致卸载组件并调用清理函数:
    • active
      现在设置为
      false
    • 最后,我们从服务器得到响应。现在,它将遇到
      false
      active
      值,并且不会更新状态
        return () => {
          active = false;
        };
    
          // active === false, 
          // this will skip `setOptions`
          if (active) {
            setOptions(...);
          }