React登录后路由跳转报错:Cannot read properties of undefined (reading 'navigate')
错误原因
你当前使用的是react-router-dom v6,该版本与旧版(v5及以下)路由API有重大差异:
- 路由组件(如Login)不会自动接收
navigation/history这类路由相关props,因此this.props.navigation必然为undefined,读取navigate属性时触发报错。 - v6中导航方法是独立的
navigate函数,而非旧版navigation.navigate的调用形式。
解决方案
方案一:改用函数组件(推荐,符合v6设计趋势)
将Login类组件改为函数组件,使用v6提供的useNavigate钩子获取导航方法:
import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; function Login() { const [loginName, setLoginName] = useState(""); const [password, setPassword] = useState(""); const [loginNameError, setLoginNameError] = useState(null); const [passwordError, setPasswordError] = useState(null); // 获取导航函数 const navigate = useNavigate(); const handleSubmit = (event) => { event.preventDefault(); // 跳转到目标路由 navigate("/employee"); }; return ( <form onSubmit={handleSubmit}> <div className="input-container"> <label>User ID</label> <input type="text" name="loginName" value={loginName} onChange={(e) => setLoginName(e.target.value)} /> <p>{loginNameError}</p> </div> <div className="input-container"> <label>Password</label> <input type="password" name="password" value={password} onChange={(e) => setPassword(e.target.value)} /> <p>{passwordError}</p> </div> <div className="button-container"> <input type="submit" value="CONNECT" /> </div> </form> ); } export default Login;
方案二:保留类组件,封装withRouter高阶组件
若需继续使用类组件,由于v6官方移除了withRouter高阶组件,需自行实现一个,用于给类组件注入路由相关方法:
- 新建
withRouter.js文件:
import { useNavigate, useLocation, useParams } from 'react-router-dom'; import React from 'react'; const withRouter = (Component) => { const WrapperComponent = (props) => { const navigate = useNavigate(); const location = useLocation(); const params = useParams(); // 将路由方法注入组件props return <Component {...props} navigate={navigate} location={location} params={params} />; }; return WrapperComponent; }; export default withRouter;
- 修改Login组件的导出和提交方法:
import React from 'react'; import withRouter from './withRouter'; // 导入自定义高阶组件 class Login extends React.Component { constructor(props) { super(props); this.state = { loginName: "", password: "", loginNameError: null, passwordError: null, }; this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit(event) { event.preventDefault(); // 使用注入的navigate方法跳转 this.props.navigate("/employee"); } render() { return ( <form onSubmit={this.handleSubmit}> <div className="input-container"> <label>User ID</label> <input type="text" name="loginName" value={this.state.loginName} onChange={(e) => (this.setState({ loginName: e.target.value }))} /> <p>{this.state.loginNameError}</p> </div> <div className="input-container"> <label>Password</label> <input type="password" name="password" value={this.state.password} onChange={(e) => (this.setState({ password: e.target.value }))} /> <p>{this.state.passwordError}</p> </div> <div className="button-container"><input type="submit" value="CONNECT"></input></div> </form> ); } } // 用高阶组件包裹后导出 export default withRouter(Login);
内容的提问来源于stack exchange,提问作者manyProblem
相关产品推荐
相关产品推荐

