Home > other >  React Router useHistory Hook matching wrong component page
React Router useHistory Hook matching wrong component page

Time:12-07

Below is a snippet from my app.js cra file, where I am using react-router-dom to navigate to various pages, the problem is, for /payment route, entering the url to payment: localhost:3000/checkout returns payment page component instead, useHistory with onClick on the header component also does the same, no error is thrown, I have already gone through the app twice searching for typos or any such fault.

The app.js snippet

import "./App.css";
import Home from "./Home";
import Checkout from "./Checkout";
import Login from "./Login";
import Payment from "./Payment";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

function App() {
  const [state, dispatch] = useStateValue();
 return (
    <Router>
      <div className="app">
        <Switch>
          <Route path="/login">
            <Login />
          </Route>
          <Route path="/checkout">
            <Checkout />
          </Route>
          <Route path="/payment">
            <Payment />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

the useHistory inside of a component:

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

export default function Subtotal() {
  const [state, dispatch] = useStateValue();
  const history = useHistory();
  return (
    <div className="subtotal">
        
      <button onClick={history.push("/payment")}>Proceed to checkout</button>
    </div>
  );
}

Quick note: everything works fine until I introduce a new route to the already existing ones

CodePudding user response:

I would suggest you upgrade your react-router-dom version to v6. Since that version is much much better than v5. Version 6 has a better algorithm to select the best possible route, with the default behavior being that it matches exact routes. Also, the order in which we list the routes does not matter anymore like it did in v5 which sometimes caused issues.

Step 1: Uninstall the old version of the package and install new one

npm uninstall react-router-dom 
npm install react-router-dom@6

Additionally, ensure that you have React 16.08 or higher. for react-router-dom v6 to work.

Step 2: Update the old code to the new one to make it work with the updates introduced in version 6

import "./App.css";
import Home from "./Home";
import Checkout from "./Checkout";
import Login from "./Login";
import Payment from "./Payment";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

function App() {
  const [state, dispatch] = useStateValue();
 return (
    <Router>
      <div className="app">
        <Routes>
          <Route path="/login" element={<Login />} />
          <Route path="/checkout" element={<Checkout />} />
          <Route path="/payment" element={<Payment />} />
          <Route path="/" element={<Home />} />
        </Routes>
      </div>
    </Router>
  );
}

Once these changes have been made, you will no longer face the same issue.

Also, note that the useHistory hook has been replaced with useNavigate.

Thus, in v5

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

const history = useHistory();

history.push("/payment")

in v6

import { useNavigate } from "react-router-dom"

const navigate = useNavigate();

navigate("/payment")

Additionally, the way you have called history.push on onClick has to be changed

Old

onClick={history.push("/payment")}

New

onClick={() => history.push("/payment")}

Note: If you have upgraded to v6 then make use of useNavigate.

References

  1. Upgrading from v5
  2. Upgrading from v5 to v6 tutorial
  • Related