React JS登录成功后无法跳转首页的实现问题排查
React登录后路由跳转失效的问题修正
代码中存在的核心错误
- 路由组件导入错误:将
BrowserRouter错误别名成Redirect导入,二者完全不是同类型的组件。BrowserRouter是应用级的路由根容器,负责注入路由上下文;Redirect是负责跳转的组件,二者不存在替代关系。 - 状态判断逻辑错误:类组件的状态存储在
this.state下,代码中判断时使用的this.islogged是组件实例上不存在的变量,永远为undefined,根本不会进入跳转分支。 - 逻辑链路断裂:编写的账号密码校验、登录状态更新逻辑没有和Formik的表单提交流程打通。当前Formik的提交回调只做了延时置位的操作,从未触发登录校验逻辑,
islogged状态永远停留在初始的false。 - 跳转实现方式错误:在按钮的
onClick事件回调中返回JSX片段无法触发页面渲染切换,因为这个返回值根本不会被React的渲染流程捕获。重定向逻辑必须写在组件的render返回的JSX树中,当对应状态满足条件时被正常渲染,才会触发路由跳转。 - 路由结构混乱:没有在应用根节点包裹全局唯一的路由根容器,Home组件内部又嵌套了一层
BrowserRouter,会导致路由上下文丢失、匹配规则混乱。 - 冗余状态问题:Formik已经完全接管了表单值的状态管理,额外维护的
loginParams状态和实际表单提交的值完全不同步,根本无法拿到用户输入的账号密码做校验。
分步修正方案
1. 调整全局路由结构
在应用最外层包裹路由根容器,配置页面路由规则、登录态守卫逻辑,避免路由上下文缺失。
// App.js 修正后核心代码 import React from 'react'; import './App.css'; import LoginForm from './forms/Login/LoginForm'; import Logo from './components/Logo'; import Footer from './Footer'; import Home from './pages/Home'; import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom'; // 登录路由守卫:校验本地token,无token直接重定向到登录页 const PrivateRoute = ({ children }) => { const hasLoginToken = localStorage.getItem('token'); return hasLoginToken ? children : <Redirect to="/login" /> } function App() { return ( <Router> <Switch> {/* 登录页路由 */} <Route path="/login"> <div className="login-page"> <Logo /> <div className='login-form'> <LoginForm /> </div> <Footer /> </div> </Route> {/* 主应用路由,受登录守卫保护 */} <PrivateRoute path="/home"> <Home /> </PrivateRoute> {/* 默认路径重定向 */} <Redirect from="/" to="/login" /> </Switch> </Router> ); } export default App;
2. 打通LoginForm的登录提交流程
删除冗余的自定义表单状态,把账号密码校验逻辑接入Formik的提交回调,在组件渲染层根据登录状态触发重定向。
// LoginForm.js 修正后核心逻辑 import React from "react"; import 'bootstrap/dist/css/bootstrap.min.css'; import { Formik } from "formik"; import * as Yup from "yup"; import Form from 'react-bootstrap/Form'; import FormGroup from 'react-bootstrap/FormGroup'; import Button from 'react-bootstrap/Button'; import { Redirect } from 'react-router-dom'; class LoginForm extends React.Component{ state = { islogged: false }; render(){ // 登录状态更新为true时,直接渲染重定向组件触发跳转 if (this.state.islogged) { return <Redirect to="/home" /> } return( <Formik initialValues={{ email: "", password: "" }} // 表单校验通过后触发提交逻辑 onSubmit={(values, { setSubmitting }) => { // 账号密码校验 if (values.email === "admin@admin.com" && values.password === "abcd1234") { localStorage.setItem("token", "T"); // 更新登录状态,触发组件重渲染 this.setState({ islogged: true }); } setSubmitting(false); }} validationSchema={Yup.object().shape({ email: Yup.string().email().required("*Campo Requerido"), password: Yup.string().required("*Campo Requerido") .min(8,"La contraseña es demasiado corta; debe tener un mínimo de 8 caracteres.") .matches(/(?=.*[0-9])/, "La contraseña debe contener un número.") })} > {(props) => { const { values, touched, errors, isSubmitting, handleChange, handleBlur, handleSubmit } = props; return ( <Form onSubmit={handleSubmit}> <h3>Iniciar Sesion</h3> <FormGroup> <Form.Label htmlFor="email">Email</Form.Label> <Form.Control name="email" type="text" placeholder="Ingresar correo..." value={values.email} onChange={handleChange} onBlur={handleBlur} className={errors.email && touched.email && "error"} /> {errors.email && touched.email && ( <div className="input-feedback">{errors.email}</div> )} </FormGroup> <FormGroup> <Form.Label htmlFor="password">Contraseña</Form.Label> <Form.Control name="password" type="password" placeholder="Ingresar contraseña..." value={values.password} onChange={handleChange} onBlur={handleBlur} className={errors.password && touched.password && "error"} /> {errors.password && touched.password && ( <div className="input-feedback">{errors.password}</div> )} </FormGroup> <Button type="submit" variant="outline-danger" block disabled={isSubmitting} > Iniciar Sesion </Button> <div style={{textAlign:"center",margin:"5px"}}> <a href='/#' >Olvido su contraseña?</a> </div> </Form> ); }} </Formik> ) } } export default LoginForm;
3. 简化Home组件结构
删除Home组件内部嵌套的路由根容器,只保留子路由匹配规则即可。
// Home.js 修正后代码 import React from 'react'; import Navbar from '../components/Navbar'; import { Switch, Route, Redirect } from 'react-router-dom'; import Reports from './Reports'; import Products from './Products'; import Users from './Users'; function Home() { return ( <div className='home'> <Navbar /> <Switch> <Route path='/users' component={Users} /> <Route path='/reports' component={Reports} /> <Route path='/products' component={Products} /> {/* Home页默认重定向到用户列表页 */} <Route path='/' render={() => <Redirect to="/users" />} /> </Switch> </div> ); } export default Home;
内容的提问来源于stack exchange,提问作者Jonathan Burgos G.
相关产品推荐
相关产品推荐

