I'm aware some changes was made with react router library in the new version, though I think I followed the changes correctly and still receiving the following error
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
Here is my code
import React, {useRef} from 'react';
import { useHistory } from 'react-router-dom';
function Home() {
const history = useHistory(); //This hook causing the error
const RouteAbout = () => {
history.push("/about");
}
return(<>
<button onClick={RouteAbout}> test </button>
</>);
}
The error refers to
const history = useHistory();
that imported from
import { useHistory } from 'react-router-dom';
How can I apply useHistory
hook with react router in a valid way?
EDIT:
App.JS
function App() {
return (
<>
<Router>
<Header/>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/portfolio">
<Portfolio />
</Route>
<Route path="/contact">
<Contact />
</Route>
</Switch>
</Router>
<Footer/>
</>
);
}
Versions
"history": "^5.0.0",
"node-sass": "^5.0.0",
"react": "^16.14.0",
"react-dom": "^17.0.2",
"react-perf-devtool": "^3.1.8",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.3",
"web-vitals": "^1.0.1"
Are you sure to have wrapped your application inside a BrowserRouter
?
This code works for me.
import ReactDOM from "react-dom";
import React from "react";
import { useHistory, BrowserRouter } from "react-router-dom";
function App() {
let history = useHistory();
const RouteAbout = () => {
history.push("/about");
};
return (
<>
<button onClick={RouteAbout}> test </button>
</>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
rootElement
);
Didn't found what causing this error, but found an alternative.
Using NavLink
although the conflict of link & button as HTML tags worked for me. A good solution will be to remove the <button>
tag and "fake" one using <a>
tag which provided by NavLink
.
<NavLink to="/about" onClick={() => window.scrollTo(0, 0)}><button>test</button></NavLink>
or
<NavLink to="/about" onClick={() => window.scrollTo(0, 0)}>test</NavLink>
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.