You need to enable JavaScript to run this app. React JS登录成功后无法跳转首页的实现问题排查
优惠活动
大模型
产品
解决方案
定价
更多

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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 21:06:06