Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.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 如何反应';s useEffect钩子是否可以访问其下定义的所有函数表达式?_Javascript_Reactjs - Fatal编程技术网

Javascript 如何反应';s useEffect钩子是否可以访问其下定义的所有函数表达式?

Javascript 如何反应';s useEffect钩子是否可以访问其下定义的所有函数表达式?,javascript,reactjs,Javascript,Reactjs,我在React中创建了一个功能组件,如下所示: import React, {useEffect} from "react"; import "./styles.css"; export default function App() { useEffect(() => logSomething(), []) const logSomething = () => console.log('whats up'); return (

我在React中创建了一个功能组件,如下所示:

import React, {useEffect} from "react";
import "./styles.css";

export default function App() {

  useEffect(() => logSomething(), [])

  const logSomething = () => console.log('whats up');
  return (<div> hello </div>)
}

import React,{useffect}来自“React”;
导入“/styles.css”;
导出默认函数App(){
useffect(()=>logSomething(),[]))
constlogsomething=()=>console.log('whats up');
返回(你好)
}
此函数运行时没有任何错误,并在控制台中成功注销“whats up”

但是,当我尝试以下操作时,我得到一个TypeError:

export default function App() {

  useEffect(logSomething(), [])

  const logSomething = () => () => console.log('whats up');
  return (<div> hello </div>)
}
导出默认函数App(){
useffect(logSomething(),[])
constlogsomething=()=>()=>console.log('whats up');
返回(你好)
}
类似地,当我尝试以下操作时,会出现TypeError:

export default function App() {

  useEffect(logSomething, [])

  const logSomething = () => console.log('whats up');
  return (<div> hello </div>)
}
导出默认函数App(){
useffect(logSomething,[]))
constlogsomething=()=>console.log('whats up');
返回(你好)
}

为什么第一个例子成功了,但是第二个和第三个例子失败了?第一个函数表达式是否以某种方式被提升?如果是这样,为什么其他两个函数表达式没有被提升?或者这只是JavaScript中函数引用工作方式的一些怪癖?

在第二个和第三个示例中,您试图在定义logSomething之前使用它。这将导致类型错误


第一个例子是有效的,因为传入useffect的匿名函数不会立即被调用,所以logSomething还没有定义也没关系。调用该函数时,const logSomething已经定义并在范围内。

此行为是由于JavaScript本身的设计,与React或
useEffect
钩子无关

在a中,
let
const
都被提升,但只有在执行相应的声明语句时才被初始化。提升和初始化之间的时间段通常称为“”。试图访问TDZ中的变量会引发
ReferenceError


在第二个和第三个示例中,尽管在同一块中声明了
logSomething
,但在执行初始化语句之前,您尝试访问它们(通过尝试运行分配的函数,或将分配的函数的引用传递给
useffect
),因此会出现错误。然而,在第一个示例中,
logSomething
在传递给
useffect
的函数中被访问,并且在执行该函数时,
logSomething
已经初始化。因此,它是有效的


TL;博士 第一个示例有效,因为:

  • logSomething
    与传递给
    useffect
    的函数在同一块范围内声明,因此在范围内可用
  • 在效果运行时,
    logSomething
    声明语句已经执行,因此当您尝试访问
    logSomething
    时,不会出现
    ReferenceError
    (与其他两种情况不同)

  • 如果您想了解更多关于TDZ的信息,这是一个很好的答案。

    我相信这是相关的:好吧,第一个示例之所以有效的主要原因是因为useEffect本质上是异步的,当它尝试调用我给它的arrow函数时,logSomething方法已经存在。其他两个示例失败,因为logSomething函数表达式当前处于“暂时死区”,当我们试图在函数中的块内访问它们时,导致它们抛出TypeError。如果“useEffect”是“setTimeout”或其他异步方法,则可能会以同样的方式工作。这很有道理,谢谢!绝对地事实上,如果您在块中创建了一个函数
    foo
    ,而不是调用
    useffect
    ,然后声明
    logSomething
    ,并在同一块的下一个语句中调用
    foo
    ,这也会起作用。这里也不会出现错误,因为
    logSomething
    将在
    foo
    运行时初始化。