16

How can I use history.push('path') in react router 5.1.2 in stateful component (class component)?

I found this, but it is a solution for a stateless component.

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

function App() {
  let history = useHistory();
}
peterh
  • 11,875
  • 18
  • 85
  • 108
Adam Gajdečka
  • 305
  • 1
  • 4
  • 13

4 Answers4

28

I had the same issue when using react router v5. When trying to change route programmatically below,

this.props.history.push({
    pathname: `/target-path`,
    state: variable_to_transfer
});

this.props.history was undefined.

Here is my solution for react router v5.

import React, { Component } from "react";
import { withRouter } from 'react-router-dom';

class MyClass extends Component {
    routingFunction = (param) => {
        this.props.history.push({
            pathname: `/target-path`,
            state: param
        });
    }
    ...
}
export default withRouter(MyClass);

Here is reference article. Hope it helps you save your time.

Update for Next.js
You should use withRouter from 'next/router' in Next.js.

import React, { Component } from "react";
import { withRouter } from 'react-router-dom';

class MyClass extends Component {
  routingFunction = (param) => {
     this.props.router.push('/dashboard');
  }
  ...
}
export default withRouter(MyClass);
iconique
  • 1,115
  • 13
  • 16
  • 2
    The key important point in this example is that withRouter() creates a new higher-order-component that will have three new props: match, location, and history. – Bluby Feb 21 '21 at 19:25
  • You really saved my time. I spent almost one day to figure out this. By the way I am new to react env – Prasad PH Aug 20 '22 at 10:08
15

This is how you can navigate to other components using history.push("/...")

In v6, use navigate("/...") in the functional component using useNavigation() hook.

In react-router-dom v6, useHistory() has been replaced to useNavigation() hook that's why history.push("/...") can't be used anymore as per the official React router documentation.

For better understanding, refer to Official Documentation

const BasicExample = () => {
  return (
    <BrowserRouter>
      <div className="App">
        <Header />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="about" element={<About />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
};
const Header = () => (
  <ul className="navbar">
    <li>
      <NavLink to="/"> Home </NavLink>
    </li>
    <li>
      <NavLink to="/about"> About </NavLink>
    </li>
  </ul>
);
const About = () => (
  <div style={{ backgroundColor: "lightgreen", height: "100vh" }}>
    <div>About</div>
    ....
  </div>
);

const Home = () => {
  const navigate = useNavigate();
  const handleClick = () => {
    navigate("/about");
  };
  return (
    <div>
      <h2>Home</h2>
      <button onClick={handleClick}>Click to navigate about page</button>
    </div>
  );
};

Live Demo in CodeSandbox

Class component

For class-based component, you can use like this

this.props.history.push({
    pathname: `/path-name`,
    state: data_to_pass //You can pass data to the component where you are navigating
});

But in v6, You can use Navigation element to navigate to other components.

Example

Set isOk state true to navigate About component.

{this.state.isOk && <Navigate to="/about" replace={true} />}
akhtarvahid
  • 9,445
  • 2
  • 26
  • 29
0

I don't have the reputation to comment on an answer, this is an addition to akhtarvahid's answer.

Here is some information you might find useful automatically give these values in props, to use the Route functionalities :

  <Route path="/about" component={About} />

Cannot read properties of undefined (reading 'push')

{match: Object, location: Object, history: Object, staticContext:undefined}

The examples above only work if you don't want to add any other value in props. if we pass our component to Route as a child, the rendering is done correctly and the route works.

<Route exact path="/" > <Home name="toto" /></Route>

But in this case Route will not pass the props to our component so we will not have histoy, location ect...

{name: "foo"}

if you use this.props.history.push("/about"); this will generate an error because history was not added to the component

Cannot read properties of undefined (reading 'push')

Here is a solution that allows the Route component with a callback

   <Exact route path="/"
  
   render={(props) =><Home name="foo" {...props}/>}
   ></Road>

{name:"foo", match: Object, location: Object, history: Object, staticContext:undefined}

-2

Just wrap everything within <BrowserRouter> and use <useHistory> to create a object literal like:

import { BrowserRouter } from 'react-router-dom';
...
...
return(
   <BrowserRouter>
      ...
      ...
   </BrowserRouter>
)

and in the function, use:

import { useHistory } from 'react-router-dom';
...
...
const history = useHistory();

function handlePush() {
...
history.push('/url');
...
}

This should pretty much workout for you. Happy to help. by RTTSS.

rttss_sahil
  • 235
  • 4
  • 10