为何React中Effect可在State定义前调用dispatch?
为什么React组件中先调用后声明的函数能正常运行,而普通JS不行?
能正常运行的React代码
"use client"; import { useEffect, useState } from "react"; export function StateTest() { useEffect(() => { setX(1); }); const [x, setX] = useState(0); return <div className="w-64 bg-black p-8 text-center text-white">{x}</div>; }
执行报错的普通JavaScript代码
function callbackLogger(callback) { console.log(callback()); } function main() { callbackLogger(() => { return helloWorld(); }); const helloWorld = () => { return "Hello World!"; }; } main();
报错信息
Uncaught ReferenceError: can't access lexical declaration 'helloWorld' before initialization
原因解释
核心差异在于回调函数的执行时机,和React代码重排无关:
普通JS报错的本质
main函数执行时,会同步调用callbackLogger并立即执行传入的箭头函数。此时helloWorld是const声明的变量,处于暂时性死区(TDZ):const声明会被提升,但在声明语句执行前无法访问该变量,因此触发引用错误。React组件正常运行的逻辑
React组件函数StateTest执行时,useEffect仅完成回调函数的注册,不会同步执行回调——回调会被React调度到组件首次渲染完成后才执行。
组件函数会完整走完整个函数体:先完成useEffect的回调注册,再执行const [x, setX] = useState(0)完成setX的声明。等React后续执行useEffect的回调时,setX已经完成声明,自然可以正常调用。
简单说:普通JS是同步执行回调,踩了暂时性死区的坑;React是把回调延后到变量声明完成后再执行,避开了这个问题。
内容的提问来源于stack exchange,提问作者kaan_atakan
相关产品推荐
相关产品推荐

