React函数组件使用this.props.history.push路由跳转报错
问题根因
你当前代码报错的核心原因有3点:
- 你使用的是函数式组件,函数组件不存在类组件的
this实例,完全无法通过this.props的方式获取路由对象,直接调用必然抛出引用错误 - 你虽然引入了
react-router-dom,但没有导入函数组件专用的路由操作Hook,不具备路由跳转能力 - 现有登录逻辑存在明显漏洞:仅传递用户名请求接口,完全没有校验用户输入的密码,极易出现越权登录问题
修复方案
React Router在函数组件中不支持类组件的this.props.history写法,需要根据你使用的版本调用对应Hook实现跳转:
- 如果你用的是当前主流的React Router v6版本,使用
useNavigateHook实现跳转 - 如果你用的是React Router v5旧版本,使用
useHistoryHook实现跳转
以下是修正后的可运行完整代码(基于React Router v6):
import React, { useState } from 'react'; // 移除未使用的useParams、useEffect,引入函数组件专用路由Hook import { useNavigate } from 'react-router-dom'; import { Button } from 'react-bootstrap'; import NavBarManu from './NavBarManu' const Login = () => { const [name, setName] = useState(""); const [password, setPassword] = useState(""); // 初始化路由跳转方法 const navigate = useNavigate(); const login = async () => { // 前端空值校验 if (!name.trim() || !password.trim()) { alert("请输入用户名和密码"); return; } try { // 请求时同时传递用户名、密码做后端校验,避免只校验用户名的漏洞 const res = await fetch(`http://localhost:3000/login?name=${encodeURIComponent(name)}&password=${encodeURIComponent(password)}`); const resp = await res.json(); console.log("登录接口返回", resp) if (resp.length > 0) { localStorage.setItem('login', JSON.stringify(resp)) // 校验通过跳转至list页面,replace参数可避免用户点击浏览器回退按钮回到登录页 navigate('/list', { replace: true }) } else { alert("用户名或密码错误,请重试") } } catch (err) { console.error("登录请求异常", err); alert("登录失败,请检查网络后重试") } } return ( <div> <NavBarManu /> <br /><h2>请登录!</h2><br /> <input type="text" placeholder="请输入用户名" name="user" onChange={(event) => setName(event.target.value)} /> <br /> <br /> <input placeholder="请输入密码" type="password" name="password" onChange={(event) => setPassword(event.target.value)} /> <br /> <br /> <button onClick={login}>登录</button> </div> ); }; export default Login;
版本适配说明
如果你使用的是React Router v5旧版本,只需要修改Hook引入和调用部分即可,其余逻辑不变:
// v5版本引入useHistory import { useHistory } from 'react-router-dom'; const Login = () => { // 初始化history对象 const history = useHistory(); // ...其余逻辑不变 // 校验通过后执行跳转 if (resp.length > 0) { localStorage.setItem('login', JSON.stringify(resp)) history.push('/list') } }
内容的提问来源于stack exchange,提问作者Anish Kumar Mohanty
相关产品推荐
相关产品推荐

