React类组件点击按钮调用navigate跳转路由不生效问题
React 类组件点击按钮路由跳转失效排查方案
核心问题点
跳转失效是三个高频问题叠加导致的,按优先级排查:
- 类组件方法this指向丢失:直接把
this.getAuthentication传给onClick时,方法执行时的this不指向当前组件实例,this.props为undefined,调用时会直接抛错。打开浏览器控制台就能看到明确的报错信息,未关注控制台报错是排查耗时久的核心原因。 - 路由API混用错误:
this.props.navigation.navigate是React Native端React Navigation库的写法,Web端React Router没有这个API。且React Router v6版本默认不会给类组件注入路由相关props,直接调用必然失效。 - 按钮默认行为打断逻辑:你设置了
type="submit",如果按钮外层包裹了form表单,点击会先触发表单默认提交刷新页面,跳转逻辑还没执行就被中断。
修复步骤
1. 修正this指向
两种方案二选一即可,推荐用类属性箭头函数的写法更简洁:
// 把普通方法改成箭头函数类属性,自动绑定当前实例this getAuthentication = (e) => { // 后续添加跳转逻辑 }
如果不想改方法写法,就在构造函数里手动绑定this:
constructor(props) { super(props); this.getAuthentication = this.getAuthentication.bind(this); }
2. 适配React Router v6 类组件路由用法
React Router v6只提供了函数组件用的路由hook,类组件需要包一层高阶组件注入跳转方法:
// 引入路由hook import { useNavigate } from 'react-router-dom'; // 编写高阶组件给类组件注入navigate方法 function withRouter(Component) { return function WrappedComponent(props) { const navigate = useNavigate(); return <Component {...props} navigate={navigate} /> } }
然后修改导出语句,用高阶组件包裹LoginPage:
export default withRouter(LoginPage);
再修改跳转逻辑,调用正确的API:
getAuthentication = (e) => { // 阻止表单默认提交行为 e.preventDefault(); // 调用注入的navigate方法跳转 this.props.navigate('/staff'); }
3. 修正按钮type属性(可选但建议)
如果这个按钮不是用来提交表单的,直接把type从submit改成button,从根源避免触发表单默认提交:
<button type="button" className="btn btn-primary" onClick={this.getAuthentication}> Enter </button>
修复后完整代码参考
import { Component } from 'react'; import { useNavigate } from 'react-router-dom'; import "bootstrap/dist/css/bootstrap.min.css"; import "./LoginPage.css"; function withRouter(Component) { return function WrappedComponent(props) { const navigate = useNavigate(); return <Component {...props} navigate={navigate} /> } } class LoginPage extends Component { getAuthentication = (e) => { e?.preventDefault?.(); this.props.navigate('/staff'); } render() { const style = { margin: "15px 0", }; return ( <div className="d-grid gap-2 mt-3"> <button type="button" className="btn btn-primary" onClick={this.getAuthentication}> Enter </button> </div> ); } } export default withRouter(LoginPage);
直接输入地址能打开页面说明路由配置本身没有问题,问题全出在前端逻辑层面,修复后即可正常跳转。
内容的提问来源于stack exchange,提问作者GhostDede
相关产品推荐
相关产品推荐

