React类组件登录后跳转路由:useNavigate替代方案咨询
你在类组件的登录逻辑中,需要验证通过后跳转到/dashboard,且browserHistory无法使用,以下是几种可行的替代方案:
先修正你代码中的错误
原代码里this.setState({...userLoginInfo.isLoggedIn = true})存在语法错误,正确的嵌套状态更新方式应该使用函数式setState,确保状态更新完成后再执行后续操作:
this.setState(prevState => ({ userLoginInfo: { ...prevState.userLoginInfo, isLoggedIn: true } }), () => { // 状态更新完成后执行存储和跳转 storeUserInfo(this.state.userLoginInfo); // 跳转逻辑写在这里 });
方案1:React Router v5 用 withRouter 高阶组件
React Router v5提供了withRouter高阶组件,能给类组件注入路由相关的props:
- 导入
withRouter:
import { withRouter } from 'react-router-dom';
- 用
withRouter包裹你的登录组件:
export default withRouter(YourLoginComponent);
- 在登录验证通过后,调用
this.props.history.push('/dashboard')实现跳转:
修改后的SignIn方法示例:
SignIn = (e) => { e?.preventDefault(); const { userLoginInfo } = this.state; const isValid = usernamePattern.test(userLoginInfo.username) && emailPattern.test(userLoginInfo.email) && passwordPattern.test(userLoginInfo.password); if (isValid) { this.setState(prevState => ({ userLoginInfo: { ...prevState.userLoginInfo, isLoggedIn: true } }), () => { storeUserInfo(this.state.userLoginInfo); this.props.history.push('/dashboard'); // 执行跳转 }); } // 错误提示逻辑 if (!usernamePattern.test(userLoginInfo.username)) { usernameErrMsg?.classList.remove('hidden'); usernameInputBorder?.classList.remove('border-slate-500'); usernameInputBorder?.classList.add('border-red-600'); } if (!emailPattern.test(userLoginInfo.email)) { emailErrMsg?.classList.remove('hidden'); emailInputBorder?.classList.remove('border-slate-500'); emailInputBorder?.classList.add('border-red-600'); } if (!passwordPattern.test(userLoginInfo.password)) { passwordErrMsg?.classList.remove('hidden'); passwordInputBorder?.classList.remove('border-slate-500'); passwordInputBorder?.classList.add('border-red-600'); } }
方案2:React Router v6 自定义适配高阶组件
React Router v6移除了withRouter,你可以自己封装一个高阶组件,把useNavigate的能力传给类组件:
- 自定义
withRouter:
import { useNavigate, useLocation, useParams } from 'react-router-dom'; const withRouter = (Component) => { const Wrapper = (props) => { const navigate = useNavigate(); const location = useLocation(); const params = useParams(); return <Component {...props} navigate={navigate} location={location} params={params} />; }; return Wrapper; };
- 同样用这个高阶组件包裹你的登录组件,然后在
SignIn方法里调用this.props.navigate('/dashboard'):
// 状态更新完成后执行跳转 this.props.navigate('/dashboard');
方案3:直接修改浏览器地址(应急方案,不推荐)
如果以上路由方案都无法使用,你可以直接修改浏览器地址,但这会触发页面刷新,破坏单页应用的体验:
window.location.href = '/dashboard';
内容的提问来源于stack exchange,提问作者islam gueniari
相关产品推荐
相关产品推荐

