You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React V6类组件登录认证时出现Cannot read properties of undefined (reading 'push')错误求助

解决React Router v6中Cannot read properties of undefined (reading 'push')错误

这个错误的核心原因是React Router v6彻底移除了对类组件的history props注入,同时useNavigate Hook只能在函数组件中使用,所以你的Login类组件里this.props.history是undefined,调用push自然会报错。下面给你两种可行的解决方案,以及顺便修正你PrivateOutlet里的逻辑问题:

方案一:将Login组件转为函数组件(推荐)

React Router v6更推荐使用函数组件配合Hooks,这样可以直接使用useNavigate:

import React, { useState } from "react";
import Wrapper from "../../../components/Wrapper";
import "./style.css"
import logo from "../../../assets/icons/logotipo_semfundo.png"
import Button from "@material-ui/core/Button";
import { MdEmail, MdLock } from "react-icons/md"
import { useNavigate } from 'react-router-dom';

const Login = () => {
  const [message, setMessage] = useState('');
  const navigate = useNavigate();
  let email = '';
  let password = '';

  const signIn = async event => {
    const data = { email, password };
    const requestInfo = {
      method: 'POST',
      body: JSON.stringify(data),
      headers: new Headers({
        'Content-Type': 'application/json'
      }),
    };

    try {
      const response = await fetch('api-link', requestInfo);
      if (!response.ok) throw new Error('Login Inválido...');
      const token = await response.json();
      localStorage.setItem('accessToken', token);
      navigate('/home', { replace: true }); // 直接使用navigate跳转
    } catch (e) {
      setMessage(e.message);
    }
  };

  return (
    <Wrapper className="login">
      <Wrapper className="login-img">
        <img src={logo} alt="logo" />
      </Wrapper>
      <Wrapper className="login-form">
        <h1 className="h1">Login</h1>
        {message && <span color="black">{message}</span>}
        <form id="loginForm">
          <Wrapper>
            <Wrapper>
              <MdEmail />
              <input
                id="email"
                type="text"
                name="email"
                placeholder="Digite um E-mail"
                onChange={e => email = e.target.value}
              />
            </Wrapper>
            <Wrapper>
              <MdLock />
              <input
                id="password"
                type="password"
                name="password"
                placeholder="Senha"
                onChange={e => password = e.target.value}
              />
            </Wrapper>
            <Wrapper>
              <Button
                onClick={signIn}
                block="true"
                color="primary"
              >
                Submit
              </Button>
            </Wrapper>
          </Wrapper>
        </form>
      </Wrapper>
    </Wrapper>
  );
};

export default Login;

方案二:用高阶组件(HOC)给类组件注入navigate

如果你不想改写为函数组件,可以写一个简单的HOC来封装useNavigate,把navigate方法传递给类组件:

1. 创建withNavigate高阶组件

// withNavigate.js
import React from 'react';
import { useNavigate } from 'react-router-dom';

export const withNavigate = (Component) => {
  return (props) => {
    const navigate = useNavigate();
    return <Component {...props} navigate={navigate} />;
  };
};

2. 修改Login组件的导出

// 导入刚才的HOC
import { withNavigate } from './withNavigate';

class Login extends Component {
  // ... 其他代码保持不变

  signIn = async event => {
    // ... 登录逻辑不变
    .then(token => {
      localStorage.setItem('accessToken', token);
      // 使用注入的navigate方法跳转
      this.props.navigate('/home', { replace: true });
    })
    .catch(e => this.setState({ message: e.message }));
  };
}

// 用HOC包裹组件后导出
export default withNavigate(Login);

额外修正:PrivateOutlet的认证逻辑错误

你的isAuth函数逻辑写反了:当存在accessToken时应该返回true(表示已认证,可以访问私有路由),但你现在的代码是返回false,会导致已登录用户被跳转到登录页。修正如下:

import React from 'react'
import { Navigate, Outlet } from 'react-router-dom'

const isAuth = () => {
  // 存在token则返回true,代表已认证
  return localStorage.getItem('accessToken') !== null;
}

const PrivateOutlet = () => {
  // 已认证 => 渲染私有页面,否则跳转登录
  return isAuth() ? <Outlet /> : <Navigate to="/" state={{ message: 'Usuário não autorizado' }} />;
}

export default PrivateOutlet

内容的提问来源于stack exchange,提问作者Luca Oliveira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:59:08