引入react-router-dom后出现React Hook调用错误的排查求助
React路由改造后Hook调用异常问题
问题背景
我有一个React父组件CreateTopMenuResultPage,点击搜索按钮会打开新的结果页,该组件会渲染在结果页的result-page-sort-menu容器中,此前所有组件渲染正常。
引入react-router-dom改造路由后,出现以下两个错误:
Rendered more hooks than during the previous render.Invalid hook call. Hooks can only be called inside of the body of a function..
错误指向所有使用useState的位置。
初步排查
最初猜测问题原因:
- React与React DOM版本不匹配
- 项目中存在多个React副本
排查结果:
- 按照官方调试方法检查,
window.React1 === window.React2返回true,排除多React副本问题。 - 运行
npm ls react-dom得到依赖树:
├─┬ @wordpress/scripts@26.6.0 │ ├─┬ @wordpress/babel-preset-default@7.20.0 │ │ └─┬ @wordpress/element@5.13.0 │ │ └── react-dom@18.2.0 deduped │ └── react-dom@18.2.0 ├─┬ rc-slider@10.3.1 │ ├─┬ rc-util@5.38.0 │ │ └── react-dom@18.2.0 deduped │ └── react-dom@18.2.0 deduped └─┬ react-router-dom@6.17.0 └── react-dom@18.2.0 deduped
补充对比信息
服务器上未使用react-router-dom、Hook逻辑完全相同的应用运行正常,其依赖树如下:
├─┬ @wordpress/scripts@26.6.0 │ ├─┬ @wordpress/babel-preset-default@7.20.0 │ │ └─┬ @wordpress/element@5.13.0 │ │ └── react@18.2.0 deduped │ ├─┬ react-dom@18.2.0 │ │ └── react@18.2.0 deduped │ └── react@18.2.0 └─┬ rc-slider@10.3.1 ├─┬ rc-util@5.38.0 │ └── react@18.2.0 deduped └── react@18.2.0 deduped
基于以上信息,我猜测问题并非版本不匹配或多React副本,但不确定是否与react-router-dom的用法有关。当前路由使用方式如下:
let navigate = useNavigate(); function handleSearch() { navigate('/search'); } return( ... <a href="#" className="theme-btn w-100 text-center margin-top-20px" onClick={handleSearch}> Search Now </a> ... );
疑问
请问这样使用useNavigate()是否存在问题?
解答
关于useNavigate的用法
你当前的useNavigate调用语法本身没问题,但有两处细节需要修正:
- 阻止默认跳转行为:
<a>标签的href="#"会触发页面锚点跳转,和navigate的路由跳转冲突,必须阻止默认行为。修改方式二选一:- 把
href改为href="javascript:void(0)" - 在
handleSearch中添加e.preventDefault():function handleSearch(e) { e.preventDefault(); navigate('/search'); }
- 把
- 确保组件在路由容器内:调用
useNavigate的组件必须被BrowserRouter(或其他路由根组件)包裹,不能在路由上下文之外使用路由Hook。
其他可能的错误原因
既然排除了版本和多副本问题,结合路由改造后的Hook异常,重点排查以下场景:
- 违反Hook调用规则:检查
CreateTopMenuResultPage及其子组件,是否在条件判断、循环、嵌套函数内部调用了useState等Hook。路由改造后新增的条件渲染逻辑,可能导致Hook调用顺序不稳定,触发Rendered more hooks than during the previous render错误。 - 组件渲染方式冲突:之前组件是直接挂载到
result-page-sort-menu容器,路由改造后如果同时使用路由渲染和ReactDOM.render手动挂载,这种混合方式会破坏Hook的调用上下文,引发异常。 - WordPress环境冲突:你使用了
@wordpress/scripts,WordPress自带的React环境可能和手动引入的react-router-dom存在隐性冲突。可以尝试调整wp_enqueue_script中依赖的加载顺序,或考虑使用WordPress官方的路由方案替代react-router-dom。
内容的提问来源于stack exchange,提问作者user1207289
相关产品推荐
相关产品推荐

