15

I'm trying to navigate away from a view by pushing into the history object. However when I try to push a route into it, I get an error message:

Property 'push' does not exist on type 'History'.

render(){
  return (
    <div className="loginWrapper">
      withRouter(({history}) => (<button onClick={()=>{history.push('/home')}} className="btn btn-primary">Pieteikties</button>))
    </div>
  )  
}

What can I do to fix this?

EDIT:

I also tried this:

logIn(){
  this.props.history.push('/new-location')
}

with a component like this:

render(){
  return (
    <div className="loginWrapper">
      <button onClick={this.logIn} className="btn btn-primary">Pieteikties</button>
    </div>
  )  
}

And it didn't work.

3 Answers 3

23

UPDATE: I found a new way to do this type of thing. Same as b4 you need to install them types:

1.- npm i react-router react-router-dom

2.- npm i -D @types/react-router @types/react-router-dom

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

interface MyComponentProps extends RouteComponentProps {
 someOfYourOwnProps: any;
 someMorePropsIfNeedIt: any;
}

interface MyComponentState {
  someProperty: any;
  another: any;
}

export class MyComponent extends React.Component<MyComponentProps, MyComponentState> {

    public state: MyComponentState;
    public constructor (props: MyComponentProps) {
        super(props);

        this.state = {
            someProperty: "",
            another: ""
        }
    }

    public onClickHandler (evt: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
        evt.preventDefault();
    }

    public componentDidMount () {
        this.props.history;
    }
   public render (): React.ReactElement<MyComponentProps> {
        return (
            <div>trol</div>
        )
    }
}

hihitl i know whats happening. Hope you sill need it.

1.- npm i react-router react-router-dom

2.- npm i -D @types/react-router @types/react-router-dom

import React from "react";
import { History, LocationState } from "history";

interface MyComponentProps {
 someOfYourOwnProps: any;
 history: History<LocationState>;
 someMorePropsIfNeedIt: any;
}

then on your component if it is a class do

class MyComponent extends Component<MyComponentProps, {}> {}

if it is a functional

const MyComponent = (props: MyComponentProps) => {}
Sign up to request clarification or add additional context in comments.

3 Comments

this is the only working solution for me in create-react-app + typescript kind of setup when I want to push history in a component.
For my cra typescript app the import { History, LocationState } from "history"; and history: History<LocationState>; was exactly what I needed. Thanks!
interface MYINTERFACE extends RouteComponentProps {} worked for me
8

Where did you define history here? There is a global window.history which is a web standard. If you want to use the react-router history, it's passed as a prop. Try props.history.push() instead.

The component must receive the history prop from react router. So it should be a direct child of a Route component, for example, or you must pass down props via its parents.

3 Comments

I don't understand your edit. What's that logIn() function? Where does it get it's this.props from? Try using this.props.history.push in the render method.
logIn() function is a method that this component has. I tried using this.props.history.push in the render method and it fails, because this.props.history is undefined.
The component must receive the history prop from react router. So it should be a direct child of a Route component, for example, or you must pass down props via it's parents. This is something that is explained in the documentation for react router. reacttraining.com/react-router/web/api/Route/route-props
1

In React 16 and above you can use Redirect from 'react-router-dom'. In your case you will get same outcomes if you use redirect instead history.

import  { Redirect } from 'react-router-dom' 

Define state in your component

this.state = {
  loginStatus:true
}

than in your render method

render () {
if(this.state.loginStatus){
    return <Redirect to='/home'  />
 }
return(
 <div> Please Login </div>
 )
}

Edit: using this.props.history

There are two things I found missing in your code. One is your login method binding. Bind your method so that you can get access to this of class. Other things is use withRouter HOC. withRouter will give you access to the this.history prop. Like so below.

import React from "react";
import { withRouter } from "react-router";

class MainClass extends Component {
  constructor(props) {
      this.login = this.login.bind(this)
   }

  logIn(){
      this.props.history.push('/new-location')
   }

   render(){
     return (
       <div className="loginWrapper">
          <button onClick={this.logIn} className="btn btn- 
          primary">Pieteikties</button>
      </div>
      )  
    }

 export default withRouter(MainClass);

2 Comments

Redirect has some caveats though such as not being able to use the browser back button.
I updated the answer. You can try this. Let me know if you get the error now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.