I'm getting an "Uncaught TypeError: Cannot read properties of undefined (reading 'push')" with react-router-dom v6

I'm getting an "Uncaught TypeError: Cannot read properties of undefined (reading 'push')" with react-router-dom v6

我遇到了那个错误 Uncaught TypeError: Cannot read properties of undefined (reading 'push')。我看过其他一些关于它的帖子,但我仍然被卡住了。我正在使用 react-router-dom v6。我认为这与传递道具或类似的东西有关。它发生的直接位置是在“主页”页面中,如果单击“登录”按钮,则会发生错误并且浏览器不会重定向到“登录”页面。这是我的文件层次结构

src
    components
        Dashboard
            Dashboard.js
        Home
            Home.js
        Login
            Login.js
        Panel
            Panel.js
        App.js
    index.js

主页有一个按钮可以转到登录页面。登录页面有一个按钮可以转到仪表板。仪表板有一个按钮可以转到面板。

这是代码 index.js

import App from "./components/App";

App.js

import React,  { Component } from "react";
import { render } from 'react-dom';
import Login from "./Login/Login";
import Home from "./Home/Home";
import Dashboard from "./Dashboard/Dashboard";
import Panel from "./Panel/Panel";

import {
    BrowserRouter as Router,
    Routes,
    Route,
} from "react-router-dom";

export default class App extends Component {
    constructor(props){
       super(props) 
    }

    render(){
        return(
            <Router>
                <Routes> 
                    <Route path="/frontend/" element={<Home />}></Route>
                    <Route path="/frontend/panel" element={<Panel />} />
                    <Route path="/frontend/login" element={<Login />}/>
                    <Route path="/frontend/dashboard" element={<Dashboard />}/>
                </Routes>
            </Router>
        );
    }
}

const appDiv = document.getElementById("app");
render(<App />, appDiv);`

首页

import React from 'react';
import { Container, Button } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles({
    root: {
        marginLeft: "auto",
        marginRight: "auto",
        width: "54%",
        textAlign: "center"
    },
    
});
const Home = (props) => {
    const handleLoginClick = () => {
        props.history.push('/frontend/login');
    }

    const classes = useStyles();

    return (
        <Container className={classes.root}>
            <h1>Home Page</h1>
            <Button variant="contained" onClick={handleLoginClick}>Login</Button>
        </Container>
           
        
    )
}

export default Home;

登录

import React, { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import  { 
    Card, 
    CardMedia,
    CardContent,
    CardActions,
    TextField,
    Button
} from '@material-ui/core';

import './Login.css';

const useStyles = makeStyles({
    root: {
        marginLeft: "auto",
        marginRight: "auto",
        width: "40%",
    },
    media: {
        height: 100,
        width: 250,
        marginLeft: "auto",
        marginRight: "auto",
    },
    signInButton: {
        marginLeft: "auto",
        marginRight: "auto"
    }
});

const Login = (props) => {
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const classes = useStyles();

    const handleLogin = () => {
        props.history.push('/frontend/dashboard');
    }


    

    return (
        <div>
            <Card className={classes.root}>
                <CardMedia className={classes.media} image="../../../static/images/some_image.jpg" title="Some Image"/>
                <CardContent>
                    <TextField type="text" placeholder="Username" variant="filled" fullWidth></TextField>
                    <TextField type="password" placeholder="Password" variant="filled" fullWidth></TextField>
                </CardContent>
                <CardActions>
                    <Button variant="contained" className={classes.signInButton} onClick={handleLogin}>Sign In</Button>
                </CardActions>
            </Card>
        </div>
    );
}

export default Login;

Dashboard.js

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
//import { getUser, removeUserSession } from './Utils/Common';
import Drawer from '@material-ui/core/Drawer';
import CssBaseline from '@material-ui/core/CssBaseline';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import List from '@material-ui/core/List';
import Typography from '@material-ui/core/Typography';
import Divider from '@material-ui/core/Divider';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import { Button } from '@material-ui/core';


const drawerWidth = 240;

const useStyles = makeStyles((theme) => ({
    root: {
      display: 'flex',
    },
    appBar: {
      width: `calc(100% - ${drawerWidth}px)`,
      marginLeft: drawerWidth,
    },
    drawer: {
      width: drawerWidth,
      flexShrink: 0,
    },
    drawerPaper: {
      width: drawerWidth,
    },
    // necessary for content to be below app bar
    toolbar: theme.mixins.toolbar,
    content: {
      flexGrow: 1,
      backgroundColor: theme.palette.background.default,
      padding: theme.spacing(3),
    },
}));

const Dashboard = (props) => {
    const classes = useStyles();
    //const user = getUser();
    
    const handleLogout = () => {
        
        //removeUserSession();
        props.history.push('/frontend');
    }

    const handleClickCreateGraphs = () => {
        props.history.push('/frontend/panel');
    }
    
    return(
        <div>
            <CssBaseline />
            <AppBar position="fixed" className={classes.appBar}>
                <Toolbar>
                    <Typography variant="h6" noWrap>
                        Welcome
                    </Typography>
                   
                </Toolbar>
                
            </AppBar>
            <Drawer
                className={classes.drawer}
                variant="permanent"
                classes={{
                paper: classes.drawerPaper,
                }}
                anchor="left"
            >
                <div className={classes.toolbar} />
                <Divider />
                <List>
                    <ListItem button key="View Graphs">
                        <ListItemText primary="View Graphs" />
                    </ListItem>
                    <ListItem button key="Create Graphs" onClick={handleClickCreateGraphs}>
                        <ListItemText primary="Create Graphs" />
                    </ListItem>
                </List>
                <Divider />
                <Divider />
                <Button variant="contained" onClick={handleLogout}>Logout</Button>

            </Drawer>
        </div>
    )
}

export default Dashboard;

面板

The panel page is way too long to post here and irrelevant to the issue. Right now, it has no onclick events to take you to another page

react-router-dom V6 中,您可以使用 useNavigate 挂钩进行编程导航,如下所示:

首页

...
import { useNavigate } from "react-router-dom";
...
const Home = (props) => {
 const navigate = useNavigate();
 
 const handleLoginClick = () => {
    navigate('/frontend/login');
 }
 ...
}