简体   繁体   中英

Invalid hook call on react router useHistory

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM