为何可在自定义函数中使用React Hooks?相关场景疑问求解
React Hooks自定义函数的运行机制解析
核心疑问拆解
你看到的FindLangKey其实不是普通函数,它本质是自定义React Hook,只是命名不符合React官方规范(官方要求自定义Hook必须以use开头,比如应该叫useFindLangKey)。React的规则从来不是“不能在普通函数里调用Hooks”,而是Hooks只能在React函数组件或其他自定义Hook中调用——这个函数符合后者,所以它内部调用useState、useContext等Hooks是完全合法的。
两种调用方式的差异原因
1. 直接在数组中调用报错
export const words = [ { langId:1, word: FindLangKey('something') } ]
这种写法是在模块加载阶段、React组件渲染周期之外执行的。React的Hooks依赖于内部维护的调用上下文:只有当代码在React函数组件执行过程中,或者被组件调用的自定义Hook执行过程中,React才会为当前组件实例创建并维护Hook的状态链表。而全局/模块级别的代码执行时,没有这个上下文,调用Hooks就会触发React的规则校验报错。
2. 包裹在函数中调用正常
export const words = ()=>{const word = FindLangKey('something');const data = [{langId:1,word:word}];return word;}
当你在React组件内部调用这个words函数时,相当于把FindLangKey的调用放到了React的渲染周期里。此时React已经为当前组件实例建立了Hook执行上下文,自定义Hook的调用符合规则,自然不会报错。
补充:代码里的不合理之处
你的FindLangKey还有两个不符合React最佳实践的地方:
useMemo里调用setText:useMemo的设计目的是缓存计算结果,不是用来执行副作用(比如修改状态),这里应该用useEffect替代,因为setState属于副作用操作。- 依赖项用
JSON.stringify(languageArray):每次数组内容变化都会生成新的字符串,会导致useMemo的回调频繁执行,性能不好。直接把languageArray放进依赖数组即可,React会对比数组的引用(如果数组是稳定的,或者你用useMemo缓存了languageArray的话)。
内容的提问来源于stack exchange,提问作者user16069077
相关产品推荐
相关产品推荐

