React嵌套含state的Hook的合法实现方案及最佳实践咨询
问题解答:自定义Hook嵌套调用规则与最佳实践
报错原因
你遇到的Invalid hook call报错是违反了React Hook的核心调用规则:
- Hook仅允许在React函数组件的顶层作用域、或者自定义Hook的顶层作用域中调用
- 你的代码中
someSubHook是在事件回调函数refresh内部调用的,此时不在React的渲染执行上下文内,无法关联到对应的组件Fiber节点,因此抛出错误。
嵌套调用自定义Hook的正确实现
带内部state的自定义Hook完全支持嵌套调用,只要保证调用位置符合上述规则即可,正确写法如下:
const {useState} = React; // 子自定义Hook(内部含state) const someSubHook = (setArtifactsStore) => { const [match, setMatch] = useState("Hello"); const subhook = () => { console.log("do some stuff with state"); setMatch("subhook"); }; return {match, subhook}; }; const useRefreshArtifacts = (setArtifactsStore) => { const [match, setMatch] = useState("Hello"); // 正确调用位置:自定义Hook顶层 const {match: subMatch, subhook} = someSubHook("sub"); const refresh = () => { console.log("do some stuff with state"); setMatch("refresh"); // 直接调用子Hook返回的方法即可 subhook(); }; return {match, subMatch, refresh}; }; function ArtifactApp(props) { const {match, subMatch, refresh} = useRefreshArtifacts(""); return (<div><button onClick={refresh}>{match} | {subMatch}</button></div>); }
封装Hook的最佳实践说明
将状态相关逻辑、请求逻辑、通用业务逻辑封装为独立的自定义Hook是React官方推荐的最佳实践,完全符合设计规范:
- 拆分逻辑处理Hook、POST请求Hook的写法符合关注点分离原则,可维护性更强
- 只要所有Hook调用遵守调用规则,存在状态依赖也完全可以正常使用,不需要刻意避免自定义Hook的嵌套和复用。
内容的提问来源于stack exchange,提问作者Tom Barber
相关产品推荐
相关产品推荐

