Sign in
Topics
Generate React UI with Prompts or Figma Import
Why does React Router DOM v6 throw useHistory not found? The hook was removed in favor of a simpler navigation pattern. This blog explains why it changed, what to use instead, and how to adapt your projects without breaking your flow.
Upgrading libraries is always exciting, but it can also bring some headaches. If you recently switched to React Router DOM v6, you may have stumbled upon a frustrating error: usehistory not found in react-router-dom
. This usually pops up when your codebase still relies on older navigation patterns that no longer exist.
Why did the React Router team remove such a widely used hook?
The answer lies in simplifying navigation and making the developer experience smoother.
In this blog, we’ll walk through why the usehistory hook disappeared, what replaced it, and how to adapt your projects. You’ll also see practical examples, common mistakes, and tips to avoid running into the same error again.
React Router has gone through several major updates over the years. In React Router DOM v6, the development team introduced big changes in navigation. One of the biggest was removing the useHistory
hook, which developers relied on to push or replace paths in the history stack. When you try to use the old hook in v6, you’ll get the error that says usehistory was not found
.
This usually happens when the code in your project is still written for React Router 5, but your dependency has already been upgraded to React Router 6. The mismatch causes the navigation functions to fail.
The fix is simpler than it looks. The team didn’t remove functionality entirely. They replaced it with a more streamlined approach: the useNavigate
hook.
Before React Router 6, developers used useHistory
to manage navigation logic inside components. For example:
1import React from "react"; 2import { useHistory } from "react-router-dom"; 3 4function App() { 5 const history = useHistory(); 6 7 const goToPage = () => { 8 history.push("/about"); 9 }; 10 11 return ( 12 <div> 13 <button onClick={goToPage}>Go to About Page</button> 14 </div> 15 ); 16} 17 18export default App; 19
In this example, the const history object came from the useHistory
hook. When you wanted to navigate, you called history.push
with a path. This would push a new entry onto the history stack, changing the current page. If you wanted to replace the entry, you used history.replace
.
React Router 6 introduced the useNavigate hook to replace this old workflow.
With the new navigation system, you no longer work directly with history. Instead, you work with the navigate function returned by useNavigate
.
1import React from "react"; 2import { useNavigate } from "react-router-dom"; 3 4function App() { 5 const navigate = useNavigate(); 6 7 const goToPage = () => { 8 navigate("/about"); 9 }; 10 11 return ( 12 <div> 13 <button onClick={goToPage}>Go to About Page</button> 14 </div> 15 ); 16} 17 18export default App; 19
Instead of writing const history
, you now write const navigate
. The navigate function becomes your main tool for moving between routes. It replaces both push
and replace
methods. This makes code shorter and easier to maintain.
The shift is easier to understand with a diagram. Here is a simple flow that shows how things changed between React Router 5 and React Router 6.
The old method depended on the history stack, while the new method connects directly to the navigate function.
A common mistake is keeping old code with the new library version. Here’s how wrong usage compares to correct usage:
Wrong Usage (Old) | Correct Usage (New) |
---|---|
const history = useHistory(); | const navigate = useNavigate(); |
history.push("/dashboard") | navigate("/dashboard") |
history.replace("/login") | navigate("/login", { replace: true }) |
Always check your React Router DOM version before writing new navigation code. Outdated snippets will cause usehistory
was not found errors.
If your project still has useHistory
, you can straightforwardly update the methods.
For example:
1// Old 2history.push("/about"); 3history.replace("/login"); 4 5// New 6navigate("/about"); 7navigate("/login", { replace: true }); 8
The push method becomes a simple navigate call, and the replace method becomes navigate with the replace option.
Navigation doesn’t just mean moving to a new page. Often, you want to pass data while navigating. The navigate function supports this with a state property.
1const navigate = useNavigate(); 2 3function goWithData() { 4 navigate("/profile", { state: { user: "John" } }); 5} 6
When you reach the destination, you can access the data with the useLocation hook.
1import { useLocation } from "react-router-dom"; 2 3function Profile() { 4 const location = useLocation(); 5 const { user } = location.state; 6 return <h1>Welcome {user}</h1>; 7} 8
This makes it easy to carry user details or other information between pages programmatically.
The navigate function can also work with the history stack by allowing negative or positive values. This is useful when replicating the browser back button or forward behavior.
1navigate(-1); // Back button 2navigate(1); // Forward 3
Each call changes the current entry in the stack and updates the current page accordingly.
If you search online, you’ll notice that some blogs still show export usehistory
in code examples. These posts are usually written for React Router 5. If you copy and paste them into a newer version, you’ll encounter errors like usehistory was not found
or found in react router mismatches.
Always check if the example matches your installed version.
When copying or pasting open code snippets, confirm that they are written for React Router DOM v6. Otherwise, you risk wasting time debugging issues that aren’t bugs but version mismatches.
Here’s a complete example of navigation using the latest approach.
1import React from "react"; 2import { BrowserRouter as Router, Routes, Route, useNavigate } from "react-router-dom"; 3 4function Home() { 5 const navigate = useNavigate(); 6 return ( 7 <div> 8 <h1>Home Page</h1> 9 <button onClick={() => navigate("/about")}>Go to About</button> 10 </div> 11 ); 12} 13 14function About() { 15 return <h1>About Page</h1>; 16} 17 18function App() { 19 return ( 20 <Router> 21 <Routes> 22 <Route path="/" element={<Home />} /> 23 <Route path="/about" element={<About />} /> 24 </Routes> 25 </Router> 26 ); 27} 28 29export default App; 30
This example shows how the function app structure combines navigation with routes. Instead of const history and push, the code uses const navigate, useNavigate
, and the navigate function.
When developers face the usehistory
was not found issue, they often wonder:
The best approach is to stick with the new methods and not mix old and new. Using the navigate function consistently keeps your project stable.
If you’re tired of fixing navigation issues manually, try Rocket.new . You can build any app with simple prompts—no code required. Write what you want your app to do, and navigation logic will be handled automatically.
The "useHistory not found in react-router-dom" error occurs when using outdated navigation code with a newer version of React Router DOM. The solution is straightforward: replace useHistory
with useNavigate
. By adopting the new hook, you’ll align with React Router DOM v6 standards and make navigation smoother across your application.