React useMemo调用未声明函数报错,与useEffect行为差异解析
问题原因解析
核心原因是useMemo与useEffect的执行时机差异,结合JavaScript变量的暂时性死区规则导致的:
useMemo的执行逻辑:useMemo的回调是在组件渲染阶段同步执行的。当组件首次渲染时,代码从上到下依次执行,遇到useMemo就会立刻调用它的回调函数。而你代码里的
handleCheckSession是用const声明在useMemo之后的,此时还没执行到变量声明的代码,变量处于「暂时性死区」,调用它自然会抛出“不是函数”的错误。useEffect的执行逻辑:useEffect的回调是在组件渲染完成后异步执行的。这时候整个组件的代码已经全部执行完毕,所有
const声明的函数都完成了初始化,所以即使handleTranslations声明在useEffect之后,回调执行时也能正常找到这个函数。
补充说明:
- 把useMemo移到
handleCheckSession声明之后,变量已经完成初始化,自然可以正常调用。 - 用useMemo模拟
componentWillMount其实并不合适——useMemo的设计初衷是缓存计算开销大的结果,而非执行初始化或副作用逻辑。如果要实现类似componentWillMount的同步初始化逻辑,直接在函数组件的顶层代码中执行即可(函数组件顶层代码会在渲染阶段同步运行,对应类组件componentWillMount的执行时机);如果不需要同步执行,用空依赖数组的useEffect就足够。
示例代码(同步初始化逻辑):
const Component = ({ someProps, ...props }) => { const handleCheckSession = async () => { await props.checkSession(); await handleWebNotificationsFetch(); }; const handleWebNotificationsFetch = async () => { // 业务代码 }; // 直接在顶层调用,对应componentWillMount的同步执行时机 handleCheckSession(); useEffect(() => { handleTranslations(); }, []); const handleTranslations = () => { // 业务代码 }; return <div>...</div>; };
内容的提问来源于stack exchange,提问作者KiYa
相关产品推荐
相关产品推荐

