如何使用带有打字稿的反应路由器 dom 导航到新页面

How to navgiate to a new page using react router dom with typescript

我想在用户登录后导航到新页面。通常我会使用 this.props.history.push("/some_other_page"); 但是这会给我以下错误。

Property 'history' does not exist on type 'Readonly & Readonly<{ children?: ReactNode; }>

Singin.tsx

interface Props {
    classes: any
}
interface State {
    email: string;
    password: string;
}

class SignIn extends Component<Props, State> {
    constructor(props: Props) {

        super(props);

        this.state = {
            email: "",
            password: "",
        };
    }

    ...

    handleLogin = async (event: any) => {

        event.preventDefault();

        const credentials: ILoginCredentials = {
            email: this.state.email,
            password: this.state.password
        }

        const res = await this.context.login(credentials);

        if (res.status === 201) {
           this.props.history.push("/dashboard");
        }

    }
   ...
}

SignIn.contextType = AuthContext;
export default withStyles(styles)(SignIn)

App.tsx

import React, { Component, Fragment } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { AuthProvider, AuthContext } from "./contexts/AuthContext";
import SignIn from "./components/signin/SignIn";
import SignUp from "./components/signup/SignUp";
import Dashboard from "./components/dashboard/Dashboard";

import { createBrowserHistory } from 'history';


import './App.scss';


const theme = createMuiTheme({
    palette: {
        primary: {
            main: '#212121',
            contrastText: '#fff',
        },
        secondary: {
            main: "#ffd600",
        }
    }
})

class App extends Component {

    componentDidMount = async () => {

    }

    createRoutes = () => {
        return (
            <Fragment>
                <Route exact path="/" component={SignIn} />
                <Route exact path="/signup" component={SignUp} />
                <Route exact path="/dashboard" component={Dashboard} />
            </Fragment>
        )
    }

    render() {
        const history = createBrowserHistory();
        return (
            <div className="root">
                <AuthProvider>
                    <MuiThemeProvider theme={theme}>
                        <BrowserRouter history={history}>
                            {this.createRoutes()}
                        </BrowserRouter>
                    </MuiThemeProvider>
                </AuthProvider>
            </div>
        )
    }
}


App.contextType = AuthContext;
export default App;

组件必须从 react-router 接收 history prop。所以它应该是 Route 组件的直接子项,如果你想要完整的历史对象,你也可以像 router 而不是 BrowserRouter 这样的上下文获取它,例如:

import { createBrowserHistory } from 'history';

import { Router } from 'react-router-dom'
const history = createBrowserHistory();



<MuiThemeProvider theme={theme}>
  <Router history={history}>
   {this.createRoutes()}
  </Router>
</MuiThemeProvider>

我认为您正在寻找在@types/react-router-dom 库中定义的 RouteComponentProps 类型。没有这个 TypeScript 将无法解释 history 属性的类型。

导入它并将传递给 React.Component 类型的道具更改为 Props & RouteComponentProps

import { RouteComponentProps } from "react-router-dom";

class SignIn extends Component<Props & RouteComponentProps, State> {

然后应该定义 history 属性。