React类组件使用redirect函数触发无效Hook调用错误求助
React Router v6 类组件路由跳转解决方案(修复Invalid hook call错误)
错误原因
你触发的Invalid hook call错误本质是:redirect是React Router v6中依赖useNavigate钩子的API,而React Hooks只能在函数组件的顶层或自定义钩子中调用,类组件不支持Hooks机制,所以直接在类组件方法中调用redirect会违反钩子规则。
正确解决方案
方案1:封装withRouter高阶组件兼容类组件
React Router v6移除了官方的withRouter,但可以手动封装一个,将路由相关方法注入类组件的props中:
首先创建withRouter.js:
import { useNavigate, useParams, useLocation } from 'react-router-dom'; import React from 'react'; const withRouter = (Component) => { const Wrapper = (props) => { const navigate = useNavigate(); const params = useParams(); const location = useLocation(); return <Component {...props} navigate={navigate} params={params} location={location} />; }; return Wrapper; }; export default withRouter;
然后修改你的User组件:
import React, { Component } from 'react' import withRouter from './withRouter'; class User extends Component { handleClick = (userId) => { // 通过props获取navigate方法实现跳转 this.props.navigate(`/user/${userId}`); } render() { return ( <div className="flex flex-row rounded-xl p-4 bg-white ring-1 ring-slate-900/5 hover:bg-slate-200 cursor-pointer" onClick={() => this.handleClick(this.props.user.id)} > ... </div> ) } } // 用withRouter包裹组件,注入路由方法 export default withRouter(User);
方案2:将类组件转为函数组件(推荐)
React Router v6原生更适配函数组件,直接转成函数组件可以更自然地使用路由钩子:
import React from 'react' import { useNavigate } from 'react-router-dom'; const User = ({ user }) => { const navigate = useNavigate(); const handleClick = (userId) => { navigate(`/user/${userId}`); } return ( <div className="flex flex-row rounded-xl p-4 bg-white ring-1 ring-slate-900/5 hover:bg-slate-200 cursor-pointer" onClick={() => handleClick(user.id)} > ... </div> ) } export default User;
关于window.location.replace的评价
这个方法确实能实现跳转,但不推荐在React Router管理的单页应用中使用:
- 会触发整页刷新,丢失单页应用的无刷新体验
- 不会更新React Router的历史栈,可能导致后退等路由行为异常
- 无法复用React Router的路由守卫、过渡动画等特性
内容的提问来源于stack exchange,提问作者Popovkov57
相关产品推荐
相关产品推荐

