React Hooks Error: Hooks can only be called inside the body of a function component

JavascriptReactjsReact Hooks

Javascript Problem Overview


I am getting this error when using the useState hook. I have this in it's basic form, looking at the react docs for a reference, but am still getting this error. I'm ready for the face palm moment...

export function Header() {
  const [count, setCount] = useState(0)
  return <span>header</span>
}

Javascript Solutions


Solution 1 - Javascript

Updated: 2018-Dec

New version of react-hot-loader is out now, link. Hooks is now working out of the box. Thank to the author, theKashey.

Check out this boilerplate https://github.com/ReeganExE/react-hooks-boilerplate

  • React Hooks
  • React Hot Loader
  • Webpack, Babel, ESLint Airbnb

Previous Answer:

First, make sure you installed react@next and react-dom@next.

Then check for you are using react-hot-loader or not.

In my case, disable hot loader & HMR could get it work.

See https://github.com/gaearon/react-hot-loader/issues/1088.

Quoted:

> Yes. RHL is 100% not compatible with hooks. There is just a few > reasons behind it: > > SFC are being converted to Class components. There is reason - to be > able to forceUpdate on HMR, as long there is no "update" method on > SFC. I am looking for other way of forcing the update (like this. So > RHL is killing SFC. > > "hotReplacementRender". RHL is trying to do React's job, and render > the old and the new app, to merge them. So, obviously, that's broken > now. > > I am going to draft a PR, to mitigate both problems. It will work, but > not today.

There is a more proper fix, which would work - cold API

You may disable RHL for any custom type.

import { cold } from 'react-hot-loader';

cold(MyComponent);

Search for "useState/useEffect" inside component source code, and "cold" it.

Updated:

As per updated from react-hot-loader maintainer, you could try react-hot-loader@next and set the config as bellow:

import { setConfig } from 'react-hot-loader';

setConfig({
  // set this flag to support SFC if patch is not landed
  pureSFC: true
});

Thank to @loganfromlogan for the update.

Solution 2 - Javascript

My problem was forgetting to update react-dom module. See issue.

Solution 3 - Javascript

Had the same issue. My problem was related to React Router. I had accidentally used

<Route render={ComponentUsingHooks} />

instead of

<Route component={ComponentUsingHooks} />

Solution 4 - Javascript

I was able to solve this by importing React's primitive hooks in the component file, then passing them into my custom hooks. For some reason, the error only occurs when I import the React hook (like useState) in my custom hook file.

I'm importing useState in my component file:

import React, {useState} from 'react'; // import useState

import {useCustomHook} from '../hooks/custom-hook'; // import custom hook

const initialState = {items: []};
export default function MyComponent(props) {
    const [state, actions] = useCustomHook(initialState, {useState});
    ...
}

Then in my hook file:

// do not import useState here

export function useCustomHook(initialValue, {useState}) {
    const [state, setState] = useState(initialValue || {items: []});
    
    const actions = {
        add: (item) => setState(currentState => {
            const newItems = currentState.items.concat([item]);
            return {
                ...currentState,
                items: newItems,
            };
        }),
    };

    return [state, actions];
}

This method has improved the testability of my hooks because I don't need to mock React's library to provide the primitive hooks. Instead, we can pass in a mock useState hook right into the custom hook's function. I think this improves code quality, as your custom hooks now have no coupling with the React library, allowing for more natural functional programming and testing.

Solution 5 - Javascript

I experienced this error while using Parcel's Hot Module Replacement, and fixed by updating react-dom to it's alpha version:

yarn add react-dom@16.7.0-alpha.0

See this issue.

Solution 6 - Javascript

I had a problem in a monorepo, where a package docz used [email protected] and the final output bundle had two react versions.

Issue on Github

Fixed it by removing the package 

Solution 7 - Javascript

Just to elaborate on @rista404's answer, including duplicate versions of react (and perhaps react-dom) will yield the same error depending on where you are using your hooks. Here are two examples...

  1. An external dependency includes another version of react in its dependencies, likely by mistake as react should usually be a peer dependency. If npm doesn't automatically dedupe this version with your local version, you may see this error. This is what @rista404 was referring to.
  2. You npm link a package that includes react in its devDependencies or dependencies. Now, for modules in this package, you may see errors if they pull a different version of react from the their local node_modules directory rather than the parent project's.

The latter can be fixed when bundling with webpack by using resolve.alias like so...

    resolve: {
        alias: {
            'react': path.resolve(__dirname, 'node_modules/react'),
            'react-dom': path.resolve(__dirname, 'node_modules/react-dom')
        }
    }

This will ensure react is always pulled from the parent project's node_modules directory.

Solution 8 - Javascript

Another solution if you are running into this when using npm link:

You can npm link react in your library as explained here: https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react

or set react in your library as peerDependency and then use npm link --only=production

Solution 9 - Javascript

The problem for me was indeed react-hot-loader.

You can disable react-hot-loader for a single component instead of the entire app using the cold method like this:

import { cold } from 'react-hot-loader'

export const YourComponent = cold(() => {

  // ... hook code

  return (
    // ...
  )
})

OR

export default cold(YourComponent)

Solution 10 - Javascript

My issue was the following:

I was doing: ReactDOM.render(Example(), app);

Whereas I should have been doing: ReactDOM.render(<Example />, app);

Solution 11 - Javascript

For those who come across this issue when using MobX and wrapping a component with an observer, make sure you use mobx-react-lite instead of mobx-react.

MAY 29 UPDATE

From mobx-react 6.0.0 onward, hook based components are now supported by mobx-react, thus, there is no need for mobx-react-lite usage anymore (if that was your problem).

Solution 12 - Javascript

JUNE 2021 ANSWER

I've been experiencing this problem with the react-electron-boilerplate app.

Many plugins and libraries like Material-UI couldn't be used in my project because of this unfortunate error and after searching a lot, I could solve the problem:

I just upgraded the react and react-dom to their latest versions.

This command got the job done!

yarn add react@latest react-dom@latest

Solution 13 - Javascript

found this workaround for react-hot-loader while that PR to fix it is inbound.

Wrap the function that calls hooks in a React.memo, preventing a hot reload if it's unchanged.

Credit for solution: https://github.com/gatsbyjs/gatsby/issues/9489

Solution 14 - Javascript

For fellow users of yarn workspaces, here's my situation and how I figured it out.

The Facebook docs on Invalid Hook Call Warning say nothing about yarn workspaces, so I assumed my config was correct. But it wasn't. You can fix the error only by using the same version across all your packages.

In the example above, you have to bump the version of react from "foo" to 16.10.1, so that it matches the react version from "bar".

Bonus: see this discussion on GitHub for a beautiful collection of emotional baggage offloaded on the Internet.

Solution 15 - Javascript

Well in my Case i was calling useSelector inside useEffect !!

Solution 16 - Javascript

If you are using Create React App, you have to update "react-scripts" version also with react and react-dom version.

 "react-scripts": "2.1.5",
 "react": "^16.8.1",
 "react-dom": "^16.8.1",
   

this combination works fine.

Solution 17 - Javascript

For me, this was occurring because I had a new version of react (16.8.6) and an old version of react-dom (16.6.1).

https://reactjs.org/warnings/invalid-hook-call-warning.html#mismatching-versions-of-react-and-react-dom

Upgrading both to @latest (16.8.6) fixed the error.

Solution 18 - Javascript

Check react and react-dom versions are strictly equal. Take care of the circumflex ^ symbol on versions.

"17.0.0" could not be the same as "^17.0.0"

npm - Carret Ranges: https://github.com/npm/node-semver#caret-ranges-123-025-004 React - Changelog: https://github.com/facebook/react/blob/main/CHANGELOG.md

That's one of the reasons to better install packages with -E or --save-exact

npm install --save --save-exact <package@vesion>

Solution 19 - Javascript

update package.json react-dom version as react

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlogandeancallView Question on Stackoverflow
Solution 1 - JavascriptNinh PhamView Answer on Stackoverflow
Solution 2 - JavascriptJLarkyView Answer on Stackoverflow
Solution 3 - JavascriptpeternycView Answer on Stackoverflow
Solution 4 - JavascriptmickmisterView Answer on Stackoverflow
Solution 5 - Javascripterica mitchellView Answer on Stackoverflow
Solution 6 - Javascriptrista404View Answer on Stackoverflow
Solution 7 - JavascriptGreg VenechView Answer on Stackoverflow
Solution 8 - JavascriptblubView Answer on Stackoverflow
Solution 9 - JavascriptprotoEvangelionView Answer on Stackoverflow
Solution 10 - JavascriptnwparkerView Answer on Stackoverflow
Solution 11 - JavascriptMarcelo CardosoView Answer on Stackoverflow
Solution 12 - JavascriptAlireza KavianView Answer on Stackoverflow
Solution 13 - JavascriptChance EakinView Answer on Stackoverflow
Solution 14 - JavascriptPaul Razvan BergView Answer on Stackoverflow
Solution 15 - JavascriptPranay DuttaView Answer on Stackoverflow
Solution 16 - Javascriptkartikag01View Answer on Stackoverflow
Solution 17 - JavascriptCody MonizView Answer on Stackoverflow
Solution 18 - JavascriptequimanView Answer on Stackoverflow
Solution 19 - JavascriptshisongyanView Answer on Stackoverflow