'useLocation: Hooks can only be called inside of the body of a function component
I'm trying to use the useLocation
hook in my function component but I'm getting Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
.
My app is structured like this:
import React, {useEffect, useState} from "react";
import Navigation from "./components/Navigation";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function App() {
// ...
return (
<Router>
<div>
// ...
<Navigation themes={themes} />
// ...
<Switch>
<Route path="/mytheme">
<MyTheme />
</Route>
</Switch>
</div>
</Router>
);
}
export default App;
With the Navigation
component (see above) looking like this:
import React from "react";
import { Link, useLocation } from "react-router-dom";
function Navigation(props) {
const location = useLocation(); // ---> this is the problem
return (
<div>
{
props.themes.map((theme, index) => {
return <Link key={index} to={"/" + theme.id}>
{ theme.name }
</Link>
})
}
</div>
);
}
export default Navigation;
Navigation works fine, but I want to use useLocation
in the Navigation
component to highlight the active "page".
Solution 1:[1]
I had same error except my function was called getSearch().
I found it very strange as everything was according to React docs.
Occurs I just had to change the function name to be named useSearch(), ie use
prefix.
Solution 2:[2]
For react-router-dom 6.x users can simply convert components to functional arrow component:
import React from "react";
import { NavLink, useLocation } from 'react-router-dom'
const Navigation = (props) => {
const location = useLocation();
return (
<div className={location.pathname === 'home' && 'is-home'}>
<NavLink to="/">Go home</NavLink>
</div>
)
}
export default Navigation
Solution 3:[3]
Here is a working example of function components that works. this can also helps to those who are using a class, and don't want to replace the react class component to function component:
In React-Router-Dom V6-> the withRouter wrapper class is not exists any more.
See: What happened to withRouter? I need it!
This question usually stems from the fact that you're using React class components, which don't support hooks. In React Router v6, we fully embraced hooks and use them to share all the router's internal state. But that doesn't mean you can't use the router. Assuming you can actually use hooks (you're on React 16.8+), you just need a wrapper.
Here is my implementation, a little more easy-to-use than doc example:
For the op of this question: you can use the ComponentWithRouterProp
to see how it should be written:
import React from 'react';
import {useLocation, useNavigate, useParams} from 'react-router-dom';
function withRouter(Component) {
function ComponentWithRouterProp(props) {
let location = useLocation();
let navigate = useNavigate();
let params = useParams();
return <Component {...props} {...{location, navigate, params}} />;
}
return ComponentWithRouterProp;
}
export default withRouter;
Use (when exporting your component):
export default withRouter(Navigation);
And, in your component, you can use:
this.props.location.pathname
this.props.params.paramName
Solution 4:[4]
For anyone may face this stupid error, i have the same error cause my function component name was "index". Just changing the name of the component was the solution to me.
Solution 5:[5]
Try using functional arrow component, that line worked for me.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Pavel K. |
Solution 2 | kuzey beytar |
Solution 3 | |
Solution 4 | Safwat Fathi |
Solution 5 | Fayeaz Ahmed |