简体   繁体   中英

react-router v4's Route doesn't pass it's props to component - in React Typescript

I just started to use React Router v4 and can't manage to use the history of Browserrouter. For example, when I try to access this.props.history.push("/") I got the error:

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

I'm using React Router v4 with Browserrouter and React with Typescript. It seems that the three props (location, history, match) from React Router's Route are not passed to it's component. Am I doing anything wrong with Typescript or with React Router?

index.tsx

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import {
    BrowserRouter as Router, Route
} from 'react-router-dom';
import Login from "./Login";
import Questionnaire from "./Questionnaire";
import Registration from "./Registration";
import NotFound from "./NotFound";
import GotNoHistory from "./GotNoHistory";
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(
    <Router>
        <Route exact={true} path="/" component={Questionnaire}/>
        <Route path="/login" component={Login}/>
        <Route path="/registration" component={Registration}/>
        <Route path="/gotNoHistory" component={GotNoHistory} />
        <Route component={NotFound}/>
    </Router>,
    document.getElementById('reactApp')
);

registerServiceWorker();

example component GotNoHistory.tsx

import * as React from 'react';
import './index.css';

class GotNoHistory extends React.Component {

    render() {
        return <div>{this.props.history.push("/")}</div>;
    }
}

export default GotNoHistory;

Update

I've discovered RouteComponentProps . I added this props to my class GotNoHistory and the error was gone. Is that the correct way to solve the problem?

import {RouteComponentProps} from 'react-router';
class GotNoHistory extends React.Component<RouteComponentProps<any>, any> {
    render() {
        return <div>Go back {this.props.history.push("/")}</div>;
    }
}

Update for Chris solution

import * as React from 'react';
import './index.css';
import {Route} from "react-router-dom";

interface Props {
}

interface State {
}

export default class GotNoHistory extends React.Component<Props & Route, State> {
    render() {
        return this.props.history.push("/");
    }
}

Results in nearly the same error: TS2339: Property 'history' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{Props & Route<RouteProps>}>' TS2339: Property 'history' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{Props & Route<RouteProps>}>'

Solved by myself.

My solution was to add the route props to the types of my props.

import {RouteComponentProps} from 'react-router';
class GotNoHistory extends React.Component<RouteComponentProps<any>> {
    render() {
        return <div>Go back {this.props.history.push("/")}</div>;
    }
}

For those who don't know, like me before, what this means <RouteComponentProps<any>> :

The parameter ist the prop type. So before it was only React.Component which means that we don't expect any props from my router. So this couldn't work out!

You should have access to it within your route components, but you need to let Typescript know you expect them as props:

import { Route, Redirect } from 'react-router-dom'
import React from 'react'


interface IProps {
}

interface IState {
}

export default class GotNoHistory extends React.Component<IProps & Route, IState> {
  render() {
      this.props.history.push("/");
  }
}

The line IProps & Route is saying the expected props is a combination of my own props (IProps, whatever you define that as, possibly nothing) and the Route props.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM