React: Hooks + multiple instances of React

Created on 27 Oct 2018  ·  285Comments  ·  Source: facebook/react

To people coming from search: please read this page first. It contains most common possible fixes!

Do you want to request a feature or report a bug?

Enhancement

What is the current behavior?

I had multiple instances of React by mistake.

When trying to use hooks, got this error:
hooks can only be called inside the body of a function component

Which is not correct since I was using function components. Took me a while to find the real cause of the issue.

What is the expected behavior?

Show the correct error message. Maybe detect that the app has multiple instances of React and say that it may be the reason of bugs.

Hooks Discussion

Most helpful comment

I had the same issue and I resolved it by adding:

 alias: {
        react: path.resolve('./node_modules/react')
      }

to resolve property in webpack config of my main app.

It's was obviously my mistake of using two copies of React but I agree that it would be great if the error message was better. I think this is maybe similar to: https://github.com/facebook/react/issues/2402

All 285 comments

So just for clarification: You were importing a hook (say useState) from a different react module than the one used to render the component?

I agree that this is confusing. I'm not sure though if we have a way of knowing if any other React module is rendering. AFAIK we try to run React in isolation as much as possible so that multiple React instances can work in the same global context without issues.

Otherwise we could probably update the error message and mention this case as well if it's not too confusing.

Yes, I compared React1 === React2 and it was false (React1 being from index.js and React2 being from the file using the hook). When this happens, hooks fail with the generic error message above.

This issue is to raise awareness of this case and maybe improve the error message in some way to help people that face this. It's probably very edge though.

Yup, i tried to npm link a package i'm creating. It throws that same error since the other package is also using hooks but with its own React. I had to publish my package to NPM and then import it directly from NPM. That way the error was gone, but i hope this is fixed since publishing a package without testing it is bad, obviously

Lerna monorepos suffer from this as well when a custom hook is defined in one package and used by another as the symlinked dependencies use their own copy of react.

I have a (hacky) workaround at the moment using npm-link-shared and a prestart npm script to essentially replace the one package's react dependency with a symlink to the other's, so they use the same instance.

"prestart": "npm-link-shared ./node_modules/<other package>/node_modules . react"

I had the same issue and I resolved it by adding:

 alias: {
        react: path.resolve('./node_modules/react')
      }

to resolve property in webpack config of my main app.

It's was obviously my mistake of using two copies of React but I agree that it would be great if the error message was better. I think this is maybe similar to: https://github.com/facebook/react/issues/2402

@mpeyper It works. Thanks

@apieceofbart That worked for me. Thanks for the suggestion. 👍

As I understand this problem arises when there are multiple copies of React in the same bundle.

Is this also a problem if two separate bundles with their own copies of React are bootstrapping their own React applications on separate dom elements, like described here: https://medium.jonasbandi.net/hosting-multiple-react-applications-on-the-same-document-c887df1a1fcd

I think the latter is a common "integration" pattern used for instance in the single-spa meta-framework (https://github.com/CanopyTax/single-spa).

I'm also having this issue even with the exact same react versions, developing hooks to be published on their own is broken when using npm-link. Getting the same unhelpful hooks can only be called inside the body of a function component message. @apieceofbart's alias solution solved this for me. Thanks so much!

Same issue here when I npm link a package to my main application. I could not get babel-plugin-module-resolver working.
It says:
Could not find module './node_module/react'
This is annoying because it prevents me from testing my component locally before publishing it.

I fixed my issue by removing the caret in "react": "^16.7.0-alpha.2"
Here is the full comment: https://github.com/facebook/react/issues/14454#issuecomment-449585005

I'm using Yarn, and fixed this by forcing resolution in my package.json:

  "resolutions": {
    "**/react": "16.7.0-alpha.2",
    "**/react-dom": "16.7.0-alpha.2"
  },

Same here!!

Just wanted to leave a note here for anyone who might have had this problem in the same manner I did.

We're running React and Rails with the react-rails gem and rendering components directly into Rails views. I was receiving this error every time a new version of the app was pushed, because Turbolinks was grabbing the new JS bundle out of the <head> which loaded up an extra instance of React. Solution was to have Turbolinks do a full page reload when it detects the bundle has changed: https://github.com/turbolinks/turbolinks#reloading-when-assets-change

This appears to have solved it for us.

I'm very excited to finally put Hooks into production, and we all owe a huge thank you to everyone who made it possible. They're a _ton_ of fun to work with and have made my code shorter and more declarative.

Just as a heads up, this issue is still relevant in the released version with the same unhelpful error message of "Hooks can only be called inside the body of a function component."

Is this something that can be fixed? I imagine it might become more and more prevalent as more devs start to implement the new features, and a clearer error message would go a long way in lieu of an outright "fix".

Thanks again for all the hard work and congrats on the release! It's really an amazing set of features.

Edit: Should have looked closer at the open PRs, just found #14690 that addresses this. Thanks @threepointone!

@taylorham The link in the commit doesn't point to anything yet. I'll wait for it, but this is an issue I have been having since using hooks in a linked _(as of npm link)_ package and it's impossible to work with it locally without publishing.
After looking severals issues, I tought this was an issue with react-hot-loader that was compiling components to classes, but even after they released a version with Hook support, it still fails the same way.
I've tried a lot of different hacks but no luck. I don't know why everybody hasn't been struck with this issue yet 🧐

@dotlouis Yeah, it's just an updated error message so far and the issue itself is still a pain.

The only thing that has worked for me at all is to make whatever app I'm developing depend on the library's instance of React by using "react": "link:../my-library/node_modules/react".

  • none of the proposed resolutions did work for me, and i've been trying all
  • trying to install on a project implementing context and a lot of HOCs
  • starting from a blank project did the trick
  • i'm keeping on looking for the cause

[ok] for me, correction was not about package.json or others double react cause : i had a global themeProvider on top of my app, coming from context. Replacing it with a "useContext Hook" ( while rewriting it as a functional comp ) seemed to be the only solution
Maybe is there an issue when

<GoodOldContext iam={a class component}>
    <BrandNewHook>
             errors : Hooks can only be called inside the body of a function component #35
     </BrandnewHook>
</GooOldContext>
export withGoodOldContext.consumer(here component)

I'm developing a component where there is an example folder that uses create-react-app.

Doing this in package.json resolved this issue for me:

{
    ...
    "dependencies": {
        "my-component": "link:..",
        "react": "link:../node_modules/react",
        "react-dom": "link:../node_modules/react-dom",
        "react-scripts": "2.1.3"
    },
    ...
}

@taylorham @DylanVann Thanks for your input guys. Unfortunately, it still does not work for me.
And I could not find any documentation about this link: protocol you used.
Basically, it says that "react-spring" (another dep that also uses react as a dependency) cannot find react-dom. Can you point me to some documentation about "react": "link:../some/path" please?

I am using linked UI package as well and I was able to fix this issue.
You need to export react renderToString from UI (linked package).
I created render function in the linked package.

Thanks @theKashey. @gaearon seems to think that it is the normal behavior. I get that React should not be loaded twice, but what is the recommended way of working with a linked local package then?

I also had issues with Lerna workspaces getting symlinked properly. This was the trick I used to get this to work. Be sure to run npm install afterwards.

"dependencies": {
    "react-dom": "file:../common/node_modules/react-dom",
    "react": "file:../common/node_modules/react"
}

There is many ways to solve it, and yarn resolutions would not usually help - it's more related to the "building tool"

  • for webpack use aliases - just "hard" alias everything ducks like react to a single file
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
     react: path.resolve(path.join(__dirname, './node_modules/react')),
   }
import {setAliases} from 'require-control';
setAliases({
  'react': path.resolve(path.join(__dirname, './node_modules/react'))
});
  • for jest use moduleNameMapper
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

@theKashey thanks for your insights, this makes sense when we consider how module resolution is done (bottom, then up the tree), but from a user point of view I don't find this very practical. When I npm link a package, I would expect it to work without having to re-wire dependencies explicitly. This makes developing a package locally quite painful.

This is a cornerstone, this is how node_modules designed to work, this is why you might have two versions of a Button in two different major versions, and dependent modules will easely find the "right" version of a package.
This is how it should work all the time.

Node.js internals are quite straightforward - try to open a file adding all known prefixes (like node_modules) or extensions(like js, ts, json); if none found go one directory up. The only way to "fix it" - replace nodejs module resolution system.

yarn pnp will do that, and might solve the problem. yarn workspaces, which might _hoist_ shared packages to the top - will also solve the problem without any "magic" involved.

npm workspaces? Does not exists right now.

I actually ended up switching my project to use workspaces. It resolves this without having to use resolutions, and the hoisting/structure is beneficial anyways.

This one was a headscratcher. I tried the webpack resolve.alias setting but it was not working, tried many settings too but never really managed to get it to work unfortunately, but here's how I finally managed to get it to work:

Here's my folder structure:

Project
|
+-- node_modules
|
+-- build
| |
| +-- index.js
|
+-- example (create-react-app)
| |
| +-- package.json

I had to modify my package.json inside the example folder, essentially pulling react from the project's 'main' node_modules based on @jmlivingston's suggestion, here's how it end up:

  "dependencies": {
    "react": "file:../node_modules/react",
    "react-dom": "file:../node_modules/react-dom",
    "react-scripts": "2.1.5"
  },

Now after that I ran npm install and then I ran npm link, that did the trick.

Hopefully this can help someone else and save some time.

So any fix to this issue? I've tried as many recommendations here as I can and no luck. I am using create-react-app and typescript. Using React/React-dom 16.8.3. This is a new project I created 2 days ago so pretty plain. I am using useSpring() and animated.div. Thanks

@guru-florida are you using react-router by any chance?

I'm using the same stack as you (typescript & create-react-app) and my issue with with the render attribute. Changing it to component did the trick.

Before:

<Route path="/signup" render={SignUp} />

After:

<Route path="/signup" component={SignUp} />

Hope it helps..!

@mikeyyyyyy No, not using React Router in this one. Thanks for the tip though cuz I was in the last project I tried using spring and had the same issue.

I had this issue with npm link (in a parcel app), the npm link .../whatever/node_modules/react doesn't seem to resolve it, works fine with non-hook components though

@tj I guess you have problem with ssr. Fast workaround is to export react functions or whole react from linked package and import it in your server package

@seeden ahh I'm not using SSR, just a SPA w/ Parcel. I have a ui pkg internally for my own stuff and an app I'm working on, both have the same react version, seems odd that there's a duplicate but maybe that's a Parcel concern

@tj oh, I see. Then good luck with this very strange issue. I spent one week with this

So any fix to this issue?

There is no issue here per se. As explained on this page, React needs useState() calls to be on the same react object as the react object as "seen" from inside react-dom. If that's not what happens for you, it means you're bundling two copies of React on the page — which is bad by itself and also breaks some other features before Hooks. So you'll want to fix it anyway. This page contains common ways to diagnose to fix it.

We're leaving this discussion open for sharing particular workarounds when people run into this problem. But it's not an issue per se that can be "fixed" by anyone but you.

I had this issue with npm link (in a parcel app), the npm link .../whatever/node_modules/react doesn't seem to resolve it, works fine with non-hook components though

Do you mind creating a small repro case?

@gaearon will do, should have time to dig in a bit more next week

Happily, require-control has fixed our issue with yarn link + SSR + styled-components 4's static context. Thanks @theKashey 👍

I tried everything here and failed. It was actually something different not documented here. It was to do with the case sensitivity of the react imports. In some cases we had:

import React from 'react'

And in others:

import React from 'React'

On some file systems (unix, osx) this causes Webpack to instantiate two copies of React.

This caused extreme confusion as I could clearly see we only have one copy of React; but it was instead the way we were importing it.

The test on the react documentation also comes out fine as it obviously uses only lower case.

This sounds like it could be worthy of a mention in the docs?

For me the reason of multiple instances of React was Webpack DllPlugin. For my vendor DLL I didn't include react and react-dom to my the entries list, however, I had other libraries which required react or react-dom so my DLL contained react and react-dom (quick check of the manifest json file can reveal that). So, when I was running the code, and import React into the application it was loading it from node_modules, but in the vendors' code React was required from their DLL file.

Overall: be careful with DLL files and make sure your included modules don't include extra dependencies that you don't need otherwise you will double import them.

I was able to fix this by updating react-hot-loader to 4.6.0

this did the trick for the npm link stuff in Parcel:

"alias": {
        "react": "../ui/node_modules/react",
        "react-dom": "../ui/node_modules/react-dom"
    }

not sure if that's what it'll try to use for a production build, seems kind of hacky but it works for development at least

@theKashey OMG man, it works! I've tried many different solutions that people suggests related to this issues: mangling with package.json deps, tracing "two reacts" across project, checking if I'm breaking the *rule of hooks` (which I'm not), but I think that your option with:

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

allows us to move our project to the next lvl, using hooks in our app-as-a-lib.

This is the resulted webpack.config.js

npm ls react

returns

[email protected] D:\code\project
`-- (empty)

for me

console.log(window.React1 === window.React2) returns true
at this point i'm thinking it's SSR causing the issue

Update. It was indeed caused By React-apollo's SSR behaviour (https://github.com/apollographql/react-apollo/issues/2541)
Upgrading to 2.3.1 fixed it

Hi guys, our team face this problem and took few days to sort it out.

the working solutions for us

Solution A: specify the package position to look for, as mentioned above

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

Solution B: use webpack resolve.modules to prioritise the right node_modules folder to look for modules

case background and why it happens

First thing first, it's not react's fault, it's not even lerna's, but react, webpack, and npm-link might need to take some responsibilities.

Case requirement:

-Non-monorepo:

  • have symlinked packages
  • symlinked package has exported component using hooks
  • creating react client side pages

    • If working on a monorepo

  • packages symlinked
  • packages got different versions of dependencies (even patch version difference), so even workspace will solve as 2 react installed
  • entrance package imported a symlinked package which use hooks

Example

Structure

- mono repo root
  - packages
    - ComponentWithHooks (peerDependency: react@^16.8.1)
    - ProductA (dependency: ComponentWithHooks, dependency: react@^16.8.4)
    - ProductB (dependency: react@^16.8.1)

Once bootstrap with workspaces, it will resolve to

- mono repo root
  - node_modules
    - react(16.8.1)
  - packages
    - ComponentWithHooks
      - node_modules (empty)
    - ProductA
      - node_modules
        - react(16.8.4)
    - ProductB
      - node_modules (empty)

And once you serve ProductA with webpack or maybe something else, it will contain 2 react instances.

Code in ProductA, will looks for ProductA/node_modules/react.

But the imported ComponentWithHooks will look for mono repo root/node_modules/react.

Why? Remember the look up rules of npm? If it cannot find the module in it's own node_modules folder, it will look for parent's node_modules...

So tools like webpack applied this rule in default perfectly.
It's nothing wrong util mono repo solution become popular.
And normal package won't notice this as most of them do not require single instance as react and redux.

I'm having this same issue using a very basic reproduction using yarn workspaces example - https://github.com/mwarger/yarn-workspace-hooks-repro

I have a component-library that is written in typescript and bundled with parcel. The example-demo is what will showcase this component-library and is a freshly created CRA app. All common packages are hoisted with yarn, so in theory there should only be one version of react available. However, the React.useEffect call I'm making in index.tsx causes the error that leads me to this GitHub issue.

Everything works until a hook is added. To reproduce the error, uncomment lines 7-9 in component-library/src/index.tsx

Hopefully I'm doing something silly that I have overlooked. Please advise as to any steps I may use to try and remedy this. Thank you!

Follow-up Edit: The below suggested debug script output prints true for me. It appears that I do not have two Reacts.

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);

Took me several hours so it might worth to take a note here.

In my case, I put a line of <script defer src="./dist/bundle.js" /> in the head of the HTML template, which works as normal when not using React hooks. All the solutions don't work and the window.React1 == window.React2 check returns true in this case.

Since webpack will inject the script tag afterward, the template should not have script tag by its own. Remove the script tag from the template make React functional with hooks (pun intended) again.

In my case I have a React app which was npm linked to a dependency I was working on. This will do the trick until I can fix a couple dependencies that need to move react and react-dom to dev and peer deps.

  1. From the app: cd node_modules/react && npm link
  2. From the app: cd node_modules/react-dom && npm link react
  3. From the linked package: npm link react

Why does it work? The error warning page mentions that "in order for Hooks to work, the react import from your application code needs to resolve to the same module as the react import from inside the react-dom package".

I am still having this issue, despite trying all of the above. Standard webpack4/babel config, with preset-env and preset-react plugins. My react/react-dom versions are pinned to 16.8.4 using yarn resolutions (where also the window.React1 === window.React2 check from above returns true).

This is on the most basic of usages:

import React, { useState } from "react";

function MyComp() {
  const [hello] = useState(0);

  return <div>HELLO {hello}</div>;
}
export default MyComp;

Does anyone have any other ideas?

EDIT: To clarify, the error is shown as react.development.js:88 Uncaught Invariant Violation: Hooks can only be called inside the body of a function component. as per the OP

In my case I have a React app which was npm linked to a dependency I was working on. This will do the trick until I can fix a couple dependencies that need to move react and react-dom to dev and peer deps.

  1. From the app: cd node_modules/react && npm link
  2. From the app: cd node_modules/react-dom && npm link react
  3. From the linked package: npm link react

Why does it work? The error warning page mentions that "in order for Hooks to work, the react import from your application code needs to resolve to the same module as the react import from inside the react-dom package".

Thanks! This works great for me. (even when I use npm link and symlink mixed situation)

I have tried all of the suggested above and was still having the error.

With a little help from @inverherive we found that enzyme-adapter-react-16 was still causing issues.

Whilst we updated react-test-renderer to the latest version (16.8.4) as it only recently added hooks support, we found via npm ls react-test-renderer that the latest version of enzyme-adapter-react-16 (1.11.2) had an internal dependancy of [email protected], which doesn't support hooks.

├─┬ [email protected]
│ └── [email protected] 
└── [email protected]

To fix this issue , as well as following @chulanovskyi's fixes, as we are using yarn we added react-test-renderer resolutions to our package.json . This forces all references of react-test-renderer to use "16.8.4".

  "resolutions": {
    "react-test-renderer": "16.8.4"
  },

This was mega frustrating, hope this can help someone else. Thanks to @chulanovskyi and @theKashey for their suggestions as well.

This will do the trick until I can fix a couple dependencies that need to move react and react-dom to dev and peer deps.

@ajcrews (I might have missed something but) I npm link an internal library in and that library has react in peerDependencies and devDependencies and I still needed your fix regardless to solve the error. Nice find!

I was about to post but found a solution

I have a component library, with an example CRA app inside for development

In the CRA app's package.json I had to modify react and react-dom to "borrow" from the root component's package.json

"dependencies": {
  "react": "link:../node_modules/react",
  "react-dom": "link:../node_modules/reac-dom",
}

This was mega frustrating, hope this can help someone else. Thanks to @chulanovskyi and @theKashey for their suggestions as well.

@Paddy-Hamilton Always check your lockfile after an install. I had encountered the same issue where yarn was duplicating react-test-renderer. With a little bit of surgery in your lockfile you could fix those:

yarn add -D react-test-renderer

-react-test-renderer@^16.0.0-0, react-test-renderer@^16.1.1:
+react-test-renderer@^16.0.0-0:
  version "16.8.4"
  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.4.tgz#abee4c2c3bf967a8892a7b37f77370c5570d5329"
  integrity sha512-jQ9Tf/ilIGSr55Cz23AZ/7H3ABEdo9oy2zF9nDHZyhLHDSLKuoILxw2ifpBfuuwQvj4LCoqdru9iZf7gwFH28A==
  dependencies:
    object-assign "^4.1.1"
    prop-types "^15.6.2"
    react-is "^16.8.4"
    scheduler "^0.13.4"

+react-test-renderer@^16.8.5:
+  version "16.8.5"
+  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.5.tgz#4cba7a8aad73f7e8a0bc4379a0fe21632886a563"
+  integrity sha512-/pFpHYQH4f35OqOae/DgOCXJDxBqD3K3akVfDhLgR0qYHoHjnICI/XS9QDwIhbrOFHWL7okVW9kKMaHuKvt2ng==
+  dependencies:
+    object-assign "^4.1.1"
+    prop-types "^15.6.2"
+    react-is "^16.8.5"
+    scheduler "^0.13.5"

A yarn check would already warn you

$ yarn check
warning "enzyme-adapter-react-16#react-test-renderer@^16.0.0-0" could be deduped from "16.8.5" to "[email protected]"

then manually dedupe it by applying the following patch:

-react-test-renderer@^16.0.0-0:
-  version "16.8.4"
-  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.4.tgz#abee4c2c3bf967a8892a7b37f77370c5570d5329"
-  integrity sha512-jQ9Tf/ilIGSr55Cz23AZ/7H3ABEdo9oy2zF9nDHZyhLHDSLKuoILxw2ifpBfuuwQvj4LCoqdru9iZf7gwFH28A==
-  dependencies:
-    object-assign "^4.1.1"
-    prop-types "^15.6.2"
-    react-is "^16.8.4"
-    scheduler "^0.13.4"
-
-react-test-renderer@^16.8.5:
+react-test-renderer@^16.0.0-0, react-test-renderer@^16.8.5:

Now you have a single version of react-test-renderer without any resolutions or webpack alias shenanigans.

For any issues related to linked packages and create-react-app follow facebook/create-react-app#6207

There is many ways to solve it, and yarn resolutions would not usually help - it's more related to the "building tool"

  • for webpack use aliases - just "hard" alias everything ducks like react to a single file
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
     react: path.resolve(path.join(__dirname, './node_modules/react')),
   }
import {setAliases} from 'require-control';
setAliases({
  'react': path.resolve(path.join(__dirname, './node_modules/react'))
});
  • for jest use moduleNameMapper
"jest": {
    "moduleNameMapper": {
      "^react$": "<rootDir>/node_modules/$1",
    },

This did it for me.

@ajcrews
Thank you! Works brilliantly to me!

I made a little test case with minimal setup using react 16.8.6, electron-webpack and RHL. Notably, when this error occurs the entire browser (in this setup, electron) just starts to use up a whole bunch of CPU time)

https://github.com/PerfectionCSGO/reeee

I've been bashing my head over this problem for 3 days now. Originally I thought RHL was the problem but removing that entirely from this project won't resolve the issue.

npm ls react returns only one result. I ensured that the above fix is applied with the latest versions + webpack alias.

The code will work in a sandbox.

In a simple webpack/website the code will work without problem. However, with electron-webpack this problem persists.

  "dependencies": {
    "i18next": "^15.0.9",
    "i18next-browser-languagedetector": "^3.0.1",
    "react": "^16.8.6",
    "react-dom": "npm:@hot-loader/react-dom",
    "react-hot-loader": "^4.8.2",
    "react-i18next": "^10.6.1",
    "source-map-support": "^0.5.11",
    "tslint": "^5.15.0"
  },
  "devDependencies": {
    "@babel/core": "^7.4.3",
    "@babel/preset-react": "^7.0.0",
    "@babel/preset-typescript": "^7.3.3",
    "@types/react": "^16.8.12",
    "@types/react-dom": "^16.8.3",
    "electron": "^4.1.3",
    "electron-builder": "20.39.0",
    "electron-webpack": "^2.6.2",
    "electron-webpack-ts": "^3.1.1",
    "typescript": "^3.4.1",
    "webpack": "^4.29.6"
  }

I hope someone can give me a pointer...

When I replace react-l18next with mobx-react-lite and use observer, it will cause the same effect.

In regards to my issue, I have resolved it by elbowing electron-webpack and go with a more 'pure' electron solution. My guess is that it's a toolchain used in webpack or babel that's incompatible.

I encountered this issue only in production. Non of the proposed solutions here helped.
My use case was a third party app that loads as a widget in another website.
When the site first loaded with the widget all worked well, but when the user navigate to a different page and returned to the page with the widget, I got the hooks error.

Note that the error only occurs when the navigation doesn't cause a page reload.

I spent hours trying to figure out what was the issue. Finally the problem was with the code snippet that loads the app bundle. On page change the bundle could load multiple times, which caused I guess to a multiple React instances in the same name space.

I fixed it by checking if the script has already been loaded.
First I exported my library to the global namespace by using Webpack's 'library' configuration:

output: {
    library: 'myLib',
    ...
}

And then in the loading script I checked if the library exists or not:

if(!window.myLib){
    var bz = document.createElement('script');
    bz.type = 'text/javascript'; 
    bz.async = true;
    bz.src = 'https://path/to/bundle.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(bz, s);
}

It might be a very specific use case but I hope this can help someone else.

So we have a main React application leveraging webpack.
We're trying to create a small React library that uses hooks, we've tried swapping out bundlers (parcel, pure babel, webpack).
When trying out our webpack implementation, we marked react and react-dom as external, so we won't include them in our bundle.
We still get the same hooks exception when using npm link.

Creating a symlink to the main application's react does work, but it's not a great dev workflow.

I'm having a rough time figuring out the underlying cause of the issue. What's producing duplicate React instance?

Hi @adriene-orange , you might find my post https://github.com/facebook/react/issues/13991#issuecomment-472740798 for more explanations.

Multi-instance caused by npm link is because node by default will look up in parent folder's node_modules for the module if it cannot find in your package.

The simplest and best solution we find for this is in your entrance package's webpack (or other tools) configuration, there's something like resolve.modules to manually set the paths and order for the paths that webpack will look for modules. Exp., resolve: { modules: [path.resolve(PACKAGE_ROOT, 'node_modules'), 'node_modules'] }, will force webpack to find modules in your entrance package root's node_module first. If cannot find the module in root, then find in the relative node_modules folder...

So we have a main React application leveraging webpack.
We're trying to create a small React library that uses hooks, we've tried swapping out bundlers (parcel, pure babel, webpack).
When trying out our webpack implementation, we marked react and react-dom as external, so we won't include them in our bundle.
We still get the same hooks exception when using npm link.

Creating a symlink to the main application's react does work, but it's not a great dev workflow.

I'm having a rough time figuring out the underlying cause of the issue. What's producing duplicate React instance?

Hi im getting this error

Invariant Violation: 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
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.

   5 | 
   6 | const useApiHelper = (url, reducer) => {
>  7 |     const [state, dispatch] = useReducer(reducer, {});
     |                                                  ^
   8 | 
   9 |     useEffect(() => {
  10 |         fetch(url).then(res => res.json())

Sample code https://stackblitz.com/edit/react-mbze9q

When i try to access this function inside test cases i'm getting above error

@abhishekguru You are calling the Hook outside of a component here in your test:

test('API test', async () => {
  const newState = useAPIHelper( // <- Called outside of a component
    'https://jsonplaceholder.typicode.com/posts',
    reducer
  )
  console.log(newState, 'new');
  // expect(newState[samUrl].loading).toEqual(true);
});

As the error states, hooks can only be called from another hook, or from within a component. In your case you could create a component for your test and render that component which uses the hook if you'd like.

Shameless plug

@abhishekguru if you have a generic hook used between multiple components and you want to test it independently of any particular component, you might consider using react-hooks-testing-library.

import { renderHook } from 'react-hooks-testing-library'

test('API test', async () => {
  const { result } = renderHook(() => useAPIHelper( // <- now called within a component
    'https://jsonplaceholder.typicode.com/posts',
    reducer
  ))

  console.log(result.current, 'new');
  // expect(result.current[samUrl].loading).toEqual(true);
});

I wanted to chime in here because we had issues with SSR only. We clear node's require.cache on file changes. This effectively gives hot reloading on the server. Clearing node's require.cache will cause issues with libraries that need to have a single copy. Here's our solution:

Object.keys(require.cache)
  .filter(key => !isSingleton(key)) // This is needed here because react cannot be deleted without causing errors
  .forEach(key => {
    delete require.cache[key]
  })

Our isSingleton function contains the list of libraries that must have a single copy. A good rule of thumb is any library that needs to be defined in peerDependencies

https://yarnpkg.com/lang/en/docs/dependency-types/#toc-peerdependencies

Also had the same issue and for me

window.React1 = require('react');
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2); // true

also returned true, tried all given suggestion but nothing worked. Finally it turned out that:

Webpack adds script tag with the bundle.js into the index.html automatically. My issue was because I was adding the bundle.js into index.html explicitly, which used to work fine before hooks.

For me issue was after babel 7 upgrade, there was no separate versions with npm ls react. Removing
"react-hot-loader/babel" from .babelrc fixed the issue temporarily.

I tried all the solutions above, but still got the error.
Eventually, I found it was caused by the package why-did-you-update, and there is a related issue for it. Just a clue for anyone uses a similar package which modifies React.

I was able to fix this in a react-native + Yarn Workspaces scenario.


In root package.json

{
  "private": true,
  "workspaces": {
    "packages": [
      "packages/*"
    ],
    "nohoist": [
      "**/react-native",
      "**/react-native/!(react)/**"
    ]
  }
}

This prevents react-native code from being hoisted (as is needed for react native), while still hoisting react, thus having all shared modules use the same react.


In the metro.config.js

module.exports = {
  watchFolders: [
    path.resolve(__dirname, '../', 'shared-module'), 
    // ...more modules
    path.resolve(__dirname, '../', '../') // to make sure the root `react` is also part of the haste module map
  ]
}

The metro config lets the bundler know where everything is.

I found a way to solve the problem for people who are locally developing a npm package for example, and they are trying to test it locally by loading their package using npm link in some sort of example app.

I switched from example app (original way of testing the component) to Storybook. When using the storybook in the project it will not load React twice as it will use the same one that component is using. While using npm link I had problems with hooks and React being loaded twice, also I was not able to get any of the above solutions to work. So Storybook solved my problem, and now I have a way to test my component through multiple scenarios and at the same time build some interactive documentation for it.

Sharing my experience with this, solved it for our project by using webpack externals for the component library to exclude react and react-dom from the build.

We are just starting with React. In my case, we are starting with Lerna monorepo with Neutrino components library package and Neutrino webapp client package. The webapp consume the build product of the linked components library. After some experimenting and getting true for the same React instance, I have looked to a way to exclude react and react-dom from the build of the components library at all.

It seems a common design pattern solution for webpack components libraries so in the components library I have added to the webpack config:

"externals": {
  "react": "react",
  "react-dom": "react-dom"
}

I didn't need to put a global script tag in the webapp package for react and react-dom. I am guessing Webpack is providing those to the component library in its require implementation the same as it provides to the webapp.

another cause of this error is mis-configuring React Router's Route,

This fails:

<Route render={MyHookedComponent}/>

, but this succeeds:

<Route component={MyHookedComponent}/>

Eg. you need to use component not render. This is an easy mistake to make since render generally works fine with class based components.

I was working on biolerplate and want to publish it to npm, and developing with the help of npm link It was working properly but after sometime started giving errors Invalid Hook call warning.
I tried using npm link ../myapp/node_modules/react but it doesn't solve out my problem,
And compared React1 === React2 it is true as well as npm ls react also done, it shows only one package.

And i am not using webpack also, i am just adding some layer outside create-react-app so i can't forced my app to use local installed react module.
Stucked with it from past 3 days._

Same as @hnagarkoti .

I experienced this warning during server side rendering (SSR) because I was using an older version of react-apollo so just wanted to leave this link here to help out the next poor soul who runs into this issue:

https://github.com/apollographql/react-apollo/issues/2541

In short, getDataFromTree doesn't support react hooks until version [email protected].

I had the same issue and I resolved it by adding:

 alias: {
        react: path.resolve('./node_modules/react')
      }

to resolve property in webpack config of my main app.

It's was obviously my mistake of using two copies of React but I agree that it would be great if the error message was better. I think this is maybe similar to: #2402

Any suggestions for doing this with create-react-app?

^ Ok, the solution I went for to solve this for create-react-app is to use react-app-rewired and customize-cra.

Here is my config-overrides.js :

const {
    override,
    addWebpackAlias,
  } = require("customize-cra");

const path = require('path'); 

module.exports = override( 
    addWebpackAlias({
        react: path.resolve('./node_modules/react')
    })
)

Example project: https://github.com/dwjohnston/material-ui-hooks-issue/tree/master

In our team we have a universal navigation component work across tens of apps, all these apps comes from react 15.0.0 to react 16.8.0, in order to enable navigation implemented above hooks, we have to bundle it with a latest react

In this case, having multiple instances of react is a fundamental requirement for us, I'd like to know whether react official team is willing to solve this issue in the future?

@dwjohnston my workaround for create-react-app was to create a webpack config for development. create-react-app internally uses webpack, webpack-dev-server, and the babel-loader so creating a webpack config just for development wasn't too bad because the dependencies are already implictly there but still a good amount of overhead to get the working correctly.

I have a issue on create-react-app: https://github.com/facebook/create-react-app/issues/6953 to add webpack alias support or similar.

👋 If anyone is also using create-react-app and experiencing this pain point, could you please give that issue a thumb ups? It might help prioritize the issue.

@ricokahler - Thanks for point that out. I'm glad to see that I'm not the only person with this issue - I've run into it with context as well.

Is there any resources that you know of that discuss this issue further?

If you're in my boat, you've added a react component package from a local directory, and now it automatically builds and install it, along with its own copy of node_modules (because it uses npm link to do this), giving your app 2 copies or React now.

I've worked around it by deleting the node_modules//node_modules before running the app. To do this automatically:

"prestart": "rimraf ./node_modules/<my_package>/node_modules"

I also faced this when doing SSR.
If you use Lerna for locally testing your React library, you might add "react/react-dom/react-router" as peerDependencies on your library, but you shouldn't add them as devDependencies. (this makes it duplicate)
You can use node --preserve-symlinks so it can lookup to the parent repo which install the peerDependencies.
For jest, you need to add the parent repo path to "jest.moduleDirectories" option so Jest can resolve them

@apieceofbart it works for me, thx!

I ran into this error when loading external React components, for example with JS modules. They are completely outside the project, loaded with dynamic import() (well jsonp for more support). To get around the issue, we pass/inject React as a property to each module. This works, but then each module is dependent on the containing React app. We're trying to remove dependencies.

As others have mentioned, this property eliminates React as usable for any type of micro front end. The issue is that there is this side-effect of creating global state in the JS runtime when importing React to use as a library.

I understand that for simple use cases, having that side-effect means that React is "easier to use." But when a web page is composed of multiple scripts from multiple bundle steps, one of them should be able to set up React (do that side effect explicitly) and the others can simply call library functions.

I still have an issue with react-bootstrap: #https://github.com/react-bootstrap/react-bootstrap/issues/3965

For anyone else stuck trying to make a lib for React, try https://github.com/whitecolor/yalc it works much better than symlinks.

@mpeyper works well. Thx

@apieceofbart That worked for me. Thanks for the suggestion. 👍

For me this problem was caused when I navigated to my project directory in PowerShell and didn't capitalize a directory name in the path. I created the project in users/…/… instead of Users/…/...
The issue was resolved when I fixed capitalization errors and recreated the project.

For me, doing:

    "react": "file:../my-library/node_modules/react",
    "react-dom": "file:../my-library/node_modules/react-dom",

Fixed most of it but wasn't enough, I kept getting the error hooks can only be called inside the body of a function component.

Turns out it was because some of my library's components where exported like so:

export default Radium(withTranslation()(MyComponent))

:x:

Where withTranslation is the HOC from react-i18next and Radium is the HOC from Radium.

And exporting them like so:

export default withTranslation()(Radium(MyComponent))

:heavy_check_mark:
Fixed everything.

Note that react-i18next was in version 10 which uses React Hooks

@mikeaustin We're having the same issue. Do you have any example of "passing/injecting React as a property to each module" ?

Still getting this issue, tried all steps:

  • yarn workspaces (via lerna)
  • checked if there is one react dep, yes

Some things that can have impact:

  • using webpack with libraryTarget
  • using typescript
$ npm ls react-dom
/xxx
└── [email protected]

$ npm ls react
/xxx
└── [email protected]

root package.json

{
  ...
  "workspaces": [
    "packages/*",
  ],
  "devDependencies": {
    ...
  },
  "dependencies": {
    "react": "16.8.6",
    "react-dom": "16.8.6"
  },
  "resolutions": {
    "react": "16.8.6",
    "react-dom": "16.8.6",
    "**/react": "16.8.6",
    "**/react-dom": "16.8.6"
  }
}

@JeremyGrieshop I had a same issue and that worked for me, Thanks.

Add "prestart" in your package.json like below:

"scripts": {
    "prestart": "rimraf ./node_modules/<my package>/node_modules",
    "start": "react-scripts start",
    "build": "react-scripts build",
  },

I had this issue and it wasnt due to multiple versions of react / react-dom
In the custom tooling I use, the require cache was being cleared out (for a purpose outside of this discussion), eg:

Object.keys(require.cache).forEach((key) => {
      delete require.cache[key];
    });

So fyi to people out there, if you are doing something like this - it will effect React Hooks, so avoid it if you can

I had the same issue and I resolved it by adding:

 alias: {
        react: path.resolve('./node_modules/react')
      }

to resolve property in webpack config of my main app.

It's was obviously my mistake of using two copies of React but I agree that it would be great if the error message was better. I think this is maybe similar to: #2402

For anyone out there using Parcel, if dist is where your compiled files are, you ought to add:

  "alias": {
    "react-mediator": "./dist"
  },

To your package.json and then you can still link (npm or yarn) the library for local development/testing.

@mikeaustin We're having the same issue. Do you have any example of "passing/injecting React as a property to each module" ?

You can use React Context to pass around "React" itself, and create a HoC to inject the property into every component. You can pass anything in api like api.React, but it gets a little tricky wrapping HoCs around those components (because now they are only available inside a component, not available to export.

const withReact = Component = props => (
  <ReactContext.Provider value={api => <Component api={api} {...props} /> } />
)

I spend couple of hours on this, if changing the source code to alter the error message and adding more info to it is not easy and you need more time, at least add this note into the doc,

_p.s: react has great documentation, but I think that page needs review._

@OliverRadini

I was able to fix this by updating react-hot-loader to ^4.6.0

Maaan, that fixed it.
@gaearon @theKashey How about adding this to https://reactjs.org/warnings/invalid-hook-call-warning.html so that people don't waste their time due to an older version of react-hot-loader ?

I thought it's quite good documented across a dozen issues already.

Hi, i'm using React in both an app and a library. I use the library inside the app. I managed to fix the two react instances issue by using :

In app webpack config :

    alias: { react: path.resolve( '__dirname', '..',  'node_modules', 'react' ) // Adapt this to match your file tree

In library webpack config

  externals: {
    react: 'react', // Case matters here
    'react-dom': 'react-dom' // Case matters here
  }

So I'm running into an issue with calling hooks from a non-transpiled file (*.js):

index.js:

import ReactDOM from 'react-dom';
import './index.css';
import App from './app';

ReactDOM.render(App(), document.getElementById('root'));

app.jsx

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
const BaseContext = React.createContext();

const initialState = {
  woo: true
};

const reducer = (state, action) => {
  switch (action.type) {
    default:
      return state;
  }
};

const Home = () => <h1>You're at home.</h1>;

const App = () => {
  // eslint-disable-next-line
  const [state, dispatch] = React.useReducer(reducer, initialState);
  return (
    <Router>
      <BaseContext.Provider value={initialState}>
        <BaseContext.Consumer>
          <div className="welcome">
            <nav>
              <ul>
                <li>
                  <Link to="/">Home</Link>
                </li>
              </ul>
            </nav>
            <header className="header">
              <h1>Welcome!</h1>
            </header>
            <Route path="/" exact component={Home} />
          </div>
        </BaseContext.Consumer>
      </BaseContext.Provider>
    </Router>
  );
};
export default App;

Any advice, assuming it isn't "Move it to JSX file and transpile"?

Nothing seems to work for me, im using a mix of stimulus and react, i have a hybrid app, started using hooks and it failed as soon as i started adding turbolinks :(

Edit: for now i solved my problem by adding data-turbolinks-track="reload" data-turbolinks-eval="false" to the script tags im using so that should do it for now

i have same question , after 4hours , i was fount that was jenkins util missing transform .babelrc files to server。。。

Why would this create the error?

$ npm ls react
[email protected] /mnt/g/development/javascript/pow-vehmain
└── [email protected]`
Invalid hook call...
ServiceVisitMaintenance
src/components/ServiceVisit/ServiceVisitMaintenance.js:6
  3 | import { ServiceVisitForm } from './ServiceVisitForm';
  4 | 
  5 | const data = [{ id: 1, description: 'Ford' }, { id: 10, description: 'Edsel' }];
> 6 | const ServiceVisitMaintenance = () => {
  7 |   const [vehicleList, setVehicleList] = useState([]);
  8 |   return (
  9 |     <div>

ServiceVisitMaintenance.js:

import React, { useState } from 'react';
import { ServiceVisitForm } from './ServiceVisitForm';
const data = [{ id: 1, description: 'Ford' }, { id: 10, description: 'Edsel' }];
const ServiceVisitMaintenance = () => {
  const [vehicleList, setVehicleList] = useState([]);
  return (
    <div>
      <ServiceVisitForm vehicleList={data} />
    </div>
  );
};

export { ServiceVisitMaintenance };

Please do check what's your react-dom version.

$ npm ls react-dom
[email protected] /mnt/g/development/javascript/pow-vehmain
└── [email protected]

I faced this when I export a connect(mapStateToProps)(MyComponent) from the library and using that library in my CRA app.

No, this was my bad error. The routine which called this used react-router-dom and used the render prop rather than the component.

Have any of you had the same issue but with gatsby?

I get the following result after I 'npm ls react':
image

and 'npm ls react-dom'
image

At first, I thought I had accidentally installed react globally, after uninstalling globally, nothing changed. Then, I tried creating an entirely new project in a different directory, 'gatsby new random-name' and added a tiny feature (add comments, following along to https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu.be) to the gatsby-starter-default to test if the error would reproduce itself. Well, to my chagrin, it did!

Any and all advice would be well-received by a frustrated plebe.

I'm still facing this issue in storybook. Is this output from npm ls correct or not?
imageimage

In my case, the problem was caused by why-did-you-update module.

User either workspace and lerna monorepo and hoist the package. that will solve problem .

we are having the same issue with SSR. it seem to work by setting externals: [“react”] in our webpack config then manually loading react/umd/react.development.js. this is a pain, however and would love to find a simpler way.

Ok so hopefully this helps somebody. We were loading the webpack runtime.js multiple times accidentally which caused multiple copies of React to exist. Make sure you only load the runtimeChunk (runtime.js) once.

If you have the problem with your Jest tests like me, this is what seems to fix it for me.
Add this in your jest.config.js

moduleNameMapper: {
    '^react$': '<rootDir>/node_modules/react/'
  }

It would be nice if this error at least pointed to the file where it's happening. I accidentally called a hook in a normal function and it was hard to debug.

I found another cause of the problem and solution for it.

My environment is electron and webpack but this might help also non-electron folks. I spent painful days trying to resolve why I get this error message after upgrading to React 16.9 (and React DOM 16.9).

In my case seemed I had two Reacts in the app, but I could not find two physical libraries in node_modules, not even using npm ls react. I even used webpack-bundle-analyzer to have a look what inside the bundle.

Eventually, I discovered that I don't have two reacts physically in the project, but React and React DOM was referenced/loaded twice in the HTML file. This can be easily checked by adding e.g. console.log("React load") to the index.js of React library.

The real source was connected to electron-webpack. react and react-dom were not marked as external therefore were loaded in the bundle as well as later from node_modules due to require used in some other module.

Solution was as simple as adding these lines to webpack.renderer.config.js:

module.exports = {
    externals: [
        "react",
        "react-dom"
    ],
};

Okay, so if anyone here uses parcel.js, for some odd reason I was able to get away with the following import: import React from 'React'; and once I started using react hooks, I got the invariant violation error not realizing it was because I was improperly importing using from 'React' instead of from 'react'. Whoops.

Have any of you had the same issue but with gatsby?

I get the following result after I 'npm ls react':
image

and 'npm ls react-dom'
image

At first, I thought I had accidentally installed react globally, after uninstalling globally, nothing changed. Then, I tried creating an entirely new project in a different directory, 'gatsby new random-name' and added a tiny feature (add comments, following along to https://www.youtube.com/watch?v=asrdFuAxPaU&feature=youtu.be) to the gatsby-starter-default to test if the error would reproduce itself. Well, to my chagrin, it did!

Any and all advice would be well-received by a frustrated plebe.

Yes I have encountered the same issue as you. I have followed the advice here...,

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);

I added React2 to index file under pages. It returns false.

Deduped means that npm should have dedeuplicated the dependency see here...

The same package doesn't have to be installed twice! It's just referenced.

Also, it moves the packages "up the tree" (flattens the tree). This makes total sense as otherwise one package would have to look in the node_modules of some other package (which would be kind of messy) and helps to simplify the dependencies.

You can validate this, as every package in your dependency graph that says deduped, can be found at least one more time in the graph, usually at a "higher level."

Though evidently the dedupping hasn't worked.

What have you tried?

I'm getting this error when trying to build with NextJS. Some components use material-ui and the problem goes away if I remove them. I don't use styled-components. I tried deleting node_modules etc. without luck. I tried adding aliases and resolves for react in my next.config.js file and package.json without luck. I'm using react 16.8.6, react-dom 16.8.6, and next 9.0.4. npm ls says there's only one of each. I am not using any npm links.

Repository: https://github.com/dancancro/questions/tree/invalid-hook-call

Codesandbox is here: https://codesandbox.io/s/github/dancancro/questions/tree/invalid-hook-call/?fontsize=14

Stackoverflow: https://stackoverflow.com/questions/57647040/nextjs-invalid-hook-call-hooks-can-only-be-called-inside-of-the-body-of-a-fun

The error is here: https://gist.github.com/dancancro/2dfafb053aaaedfade406fd4f67eb68a
... render -> renderToString -> ReactDOMServerRenderer.read -> ReactDOMServerRenderer.render -> Object.WithStyles [as render] ...

The offending hook is a useStyles() call on line 17428 of the following file in a withStyles function. Search for "var classes = useStyles(props)". The problem is with nextjs-generated code. The code I wrote doesn't use withStyles or any hooks or any functions that start with "use*"

https://raw.githubusercontent.com/dancancro/questions/invalid-hook-call/.next/static/development/pages/index.js

UPDATE: removing this from my next.config.js solved the problem:

    webpack: config => {
        config.externals = [
            '/'
        ]
        return config
    },

I discovered a workaround by deleting react and react-dom from my linked package's node_modules folder.

I'm in the same boat as a lot of you. I have a library package I'm working on locally, and I don't want to go through the trouble of publishing it each time I need to see changes in my application package. I linked it and started getting this error.

Here's the workaround:

  • Package A: your library code package, has been npm link'd
  • Package B: your application code package. Has a symlink in your node_modules folder for package A
  1. Build package A. Mine outputs its assets to dist/, including it's node_modules
  2. In package A's distributed node_modules folder, delete react and react-dom
  3. ???
  4. Profit!

Note that I had installed the same version of React in both packages. You'll have to restart any running processes.

Remove incompatible why-did-you-update works for me. (https://github.com/maicki/why-did-you-update/issues/52)

incompatible why-did-you-update

@bertho-zero use can use the new devtools or my hook useWhyDidYouUpdate

@brunolemos It's great but more constraining because you have to put it on each component.

@dmart914's solution solved the issue for me. I too have packages linked so that I can test my library without publishing a change... has anyone found a workaround for this? It's not a great experience to publish an open-source library and have to document deleting specific NPM packages for the hooks to magically start working...

The solution around removing the linked package's react module doesn't work if that package has tests that require react (e.g. @testing-library/react or @testing-library/react-hooks), so it looks like we still need a better way to handle this.

My application consists of two parts. The main web application and a module which gets dynamically loaded into the web application. Both web application and the module uses React 16.9.0.
The module is loaded into the web application using React.lazy() and dynamic import() statement.
When the module is loaded the "Invalid hook call" error is thrown.

In my case since the main application and the module are built separately they are not aware of each other and going to have their own copy of react. I tried the following suggestions found in the thread but didn't solve the issue.

  1. Adding an alias in the module's webpack.config which points to the main application's react as suggested by apieceofbart .
    alias: {
    react: path.resolve('../../node_modules/react')
    }

  2. Tried to point the react dependencies in the module's package.json to the main application.
    "dependencies": {
    "react-dom": "file:../common/node_modules/react-dom",
    "react": "file:../common/node_modules/react"
    }

I think react has to support running multiple copies when it comes to dynamically loaded modules.

Based on some of the responses above, here's what worked for me:

  1. Added the following to config/webpack.config.js
externals: {
  react: {
    root: 'React',
    commonjs2: 'react',
    commonjs: 'react',
    amd: 'react'
  },
  'react-dom': {
    root: 'ReactDOM',
    commonjs2: 'react-dom',
    commonjs: 'react-dom',
    amd: 'react-dom'
  }
}
  1. Edited package.json
"devDependencies" : {
  ...
  "react": "^16.9.0",
  "react-dom": "^16.9.0",
}
"peerDependencies": {
  "react": "^16.9.0",
  "react-dom": "^16.9.0"
}
  1. Edited public/index.html
<head>
  <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
...

After that, I was able to run hooks in my library using the React loaded from CDN, while Jest still loaded the react copy from node_modules (installed from devDependencies).

Hope that helps

I have face this issue when I try to change my component from functional to classfull component and I also get this error so here is my solution regarding this error hope it helps in your case also.

try use higher order component in this case

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/styles';
import Button from '@material-ui/core/Button';

const styles = theme => ({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});

class HigherOrderComponent extends React.Component {

render(){
const { classes } = this.props;
return (
Higher-order component
);
}
}

HigherOrderComponent.propTypes = {
classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(HigherOrderComponent);

I'm using Yarn, and fixed this by forcing resolution in my package.json:

  "resolutions": {
    "**/react": "16.7.0-alpha.2",
    "**/react-dom": "16.7.0-alpha.2"
  },

Did you add in the Parent or Child package?

Based on some of the responses above, here's what worked for me:

  1. Added the following to config/webpack.config.js
externals: {
  react: {
    root: 'React',
    commonjs2: 'react',
    commonjs: 'react',
    amd: 'react'
  },
  'react-dom': {
    root: 'ReactDOM',
    commonjs2: 'react-dom',
    commonjs: 'react-dom',
    amd: 'react-dom'
  }
}
  1. Edited package.json
"devDependencies" : {
  ...
  "react": "^16.9.0",
  "react-dom": "^16.9.0",
}
"peerDependencies": {
  "react": "^16.9.0",
  "react-dom": "^16.9.0"
}
  1. Edited public/index.html
<head>
  <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
...

After that, I was able to run hooks in my library using the React loaded from CDN, while Jest still loaded the react copy from node_modules (installed from devDependencies).

Hope that helps

No offence, but it is disturbing that solutions like this have to be followed. I have been trying to get this bug resolved for the last couple of days without relying on such hacks.

I am working on a reusable library that contains components using hooks. I need to test them in actual projects before publishing them. The only solution for this is to use yarn|npm link. I bundle the library using rollup, and I can verify that the bundle does not contain a version of react. When I bundle (webpack) the app that makes use of the library the bug/issue appears. This happens for bare create-react-app and a next.js apps too. Both frameworks use webpack in the background.

Has anyone found a sustainable solution yet?

By ditching npm|yarn link completely, I was able to resolve the issue. Instead, I use this lovely library, which is agnostic of your project structure. It also allows you to keep using webpack as your bundler, so you do not have to declare _react_ and _react-dom_ as an external or alias. Unfortunately, it introduces some new directories and lock files to the project, but hey it works...locally and even inside our docker containers.

Maybe this will be at list a little bit helpful:

Link

@GabrielBB thank's, it's work for me

@dmart914 thanks! So far the only workaround that works for me :)

Currently getting the React Invalid Hook Call warning when using a minimal, straightforward setup.

This function component:

  1. Uses the same version for React and ReactDOM.
  2. Follows the Rules of Hooks.
  3. Only has one copy of React.

__Dependencies__
[email protected]
[email protected]
[email protected]
[email protected]

And running webpack test.js -o main.js to build.

I expect this file to:

  • Render the box.

    • Pause the debugger before calling React.useState.

    • Create a boolean test and update callback updateTest.

    • Throws the React error.

    • On render perform the React.useEffect callbacks.

    • Throws the React error.

Am I doing something wrong, or is there something else going on?

// test.js
import React, { createElement as el } from 'react';
import ReactDOM from 'react-dom'; 

function Item() {
  debugger;
  const [test, updateTest] = React.useState(false); // Throws React error.

  React.useEffect(function checkTest() { // Throws React error.
    console.log("checking test", test);
  }, [test]);

  React.useEffect(function tester() { // Throws React error.
    if (!test) {
      setTimeout(() => {
        console.log("changing value for test");
        updateTest(true);
      }, 1000);
    }
  }, [test]);

  return el('div', {style: {width: '300px', height: '300px', 'background-color': 'green', border: '1px solid red'}});
}

function render() {
  let root = document.querySelector('#primary');
  if (!root) {
    root = document.createElement('div');
    document.body.appendChild(root);
  }

  ReactDOM.render(Item(), root);
}

render();

You forgot to actually create an element. You're synchronously invoking Item() before you reach the ReactDOM.render call. You need to pass el(Item).

True! Thank you for the info.

Am in a similar situation to some of the other commenters. I am using webpack to transpile some react components (some of which use hooks) and placing the transpiled code into a lib folder. I added react to the externals field of the webpack config so it does not get bundled with the component code. I would like to use these components in two separate projects - these components are common between them and so we would like to develop them in one place and have the updates be reflected in both apps.

If the dependency is added using common-components: file:../../common-components/lib in package.json then the components load perfectly, however running webpack doesn't update the components immediately - instead I must run yarn upgrade common-components and then restart the dev server.

If the dependency is added using common-components: link:../../common-components/lib then rerunning webpack will update the files in the main app's node_modules (since it is using a symlink now), but I am getting the above error of multiple instances of react. I suppose it is now using the react version in the common-components/node_modules folder.

Is there a way to use symlinks (i.e. common-components: link:../../common-components/lib), while also making sure the linked components use the react found in the main app's node_modules folder? Since I am planning on using these components in both apps I cannot link the react package from one of them into the common components library and I would like to avoid linking both the main apps' reacts to the one used in the common components package. I have seen some comments referring to the webpack resolve field which sounds promising but I am unable to get it to work. Any help would be greatly appreciated!

edit: for anyone interested in our use case, we ended up changing the build step to simply copy the files into the two projects in which they are needed, and avoiding transpiling altogether.

One quick work around would be not to publish the package, but just push it to github and import it into your project using yarn add <git-url>.

One quick work around would be not to publish the package, but just push it to github and import it into your project using yarn add <git-url>.

The reason many of us use npm link and npm package relative paths is to develop and test the code without having to publish changes to NPM or GitHub before we know it will work.

We've ran into this issue being related to https://github.com/facebook/react/issues/13972#issuecomment-447599035 in that I think this can also be caused by a Webpack'd Node server. Our use case was an integration test running within Jest which ran webpack() programmatically to build the server prior to executing the tests. The issue, I believe, is related to how ESM and CJS can exist at the same time.

Take this example for instance:

// node express server, doing server-rendering
import React from 'react';
import { ApolloProvider } from '@apollo/react-common';
import { renderToStringWithData } from '@apollo/react-ssr';

res.send(await renderToStringWithData(<ApolloProvider><App /></ApolloProvider>)

What I am seeing while in a debugger session is that we can get two different instances of React in the compiled version of this file:

_react: {Children, ...}
_react2: {default: {Children, ...}

Where
_react is from the ESM import React from 'react' in this file
_react2 is from the CJS var _react = _interopRequireDefault(require("react")); from within node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js

I believe this caused the reference to React to not be equal in the two places (server-render file, and inside @apollo/react-ssr's bundle) and thus caused the error to be thrown.

We found that this was probably caused by programmatic usage of webpack() from within the test, and have refactored those tests to be end-to-end tests. Lesson being for us that if the issue is happening only in test code, you may have overly complicated tests.

I managed to solve it with yarn:

cd to myApp/node_modules/react and yarn link

then in your library, run yarn link react

Now your library is using the exact same react version as your main app

I tried to set react as a peer Dependancy in my lib but then the lib wouldn't build

How one can fix this using create-react-app without ejecting or switching to yarn?

You can just use the exact same technique using npm link. No ejecting necessary.

Linking react is not the best idea when you work on multiple projects with different versions.

@woles you're totally right but in my case, it solves my 'hooks' problem. I hope react developers come up with a better solution

Hi,
I fixed this bug after hours realising that I accidentally used the component falsely inside react router.

My app was working but in one component I could not add useState at all. the reason was that I used the component inside react routers render method without the higher order function like this:
<Route exact path="/path" render={ ComponentCausingTheErrorMesage }/>
switching to
<Route exact path="/path" component={ ComponentNowWorkingAgain }/>
fixed it for me

I was using npm link between an app and a module I was actively working on, and I had to fix it by linking the app's react and react-dom to the module, then linking the module to the app:

in app:

  1. cd node_modules/react && npm link
  2. same for react-dom

in module:

  1. npm link react && npm link react-dom
  2. npm link

in app:

  1. npm link [module-name]

Hope this helps someone

We had hooks working client-side but were hitting this error on SSR. My colleague solved this it with the following in our server-side webpack config:

const nodeExternals = require('webpack-node-externals');

const serverConfig = () => {
  // lots of config, then:
  externals: [
    nodeExternals({
      modulesFromFile: true,
    }),
  ],
}

I managed to solve it with yarn:

cd to myApp/node_modules/react and yarn link

then in your library, run yarn link react

Now your library is using the exact same react version as your main app

I tried to set react as a peer Dependancy in my lib but then the lib wouldn't build

This works just beautful

Just ran into this issue, when using electron-webpack, react and material-ui at the same time. When i try to use anything from material-ui - i get this error (e.g. try to use

Hi ZVER3D, try reading my earlier comment. Hope it helps!

I was using npm link between an app and a module I was actively working on, and I had to fix it by linking the app's react and react-dom to the module, then linking the module to the app:

in app:

1. `cd node_modules/react && npm link`

2. same for `react-dom`

in module:

1. `npm link react && npm link react-dom`

2. `npm link`

in app:

1. `npm link [module-name]`

Hope this helps someone

Sweet baby moses, this helped me so much. Didn't even consider the problem being different versions of react!! I'm building a component locally to publish to NPM but have a separate project to test it locally, using npm link. Obviously (now) they're both using different versions of react. D'oh!

Hi ZVER3D, try reading my earlier comment. Hope it helps!

Thanks for pointing me in the right direction. Another solution was to add the ui library, that im using into "whiteListedModules". The only problem would be that you would have to do it for all modules that require react to compile.
So, in package.json i wrote this:

"electronWebpack": {
    "whiteListedModules": [
      "@material-ui/core",
      "@material-ui/icons"
    ]
  }

I'm developing a React application using the monorepo approach. I have a main app (brush) and a react library component (react-gbajs).

So when I try to render my react-gbajs component, I have this error about multiple instances of React. If I copy and paste the same code on brush I don't have any problem.
I followed many approaches to fix it, but I none of them solved it (change build on Webpack, Yarn's workspace, npm link...)

I tried to debug to check if I really have two copies os React (using console.log(window.React1 === window.React2) from React's doc), but it evaluates as true!
(a VERY BAD workaround that I'm using now is to pass the hooks as prop: <GBAEmulator useEffect={useEffect} />... but I really don't want to merge it)

Anyone have some ideia to fix it?

My project is open source and I'm adding this new react library component at this branch: https://github.com/macabeus/klo-gba.js/blob/ac18f4d42b122c333622f502947135c2de217ce2/react-gbajs/src/index.js#L251-L274

Hi all,

I have an app (myApp) that uses as dependency a custom library (myDepPackage). Both of them are using webpack as a build tool and of course I was having the same error. None of the above solutions worked for me. What it did, was to force webpack NOT to include react into the final bundle of the custom library (myDepPackage). The only configuration line I had to add to the webpack config (of the myDepPackage) is the below:

externals: {
  react: "react",
},

You can learn more about the "externals" option here: https://webpack.js.org/configuration/externals/#externals

@tsevdos Veeeery thank you!!! ❤️
It solved my problem that I said at the previous comment.

For us, the problem was that we have an embeddable React app that gets loaded in the page from a WordPress shortcode and gets mounted on a div with a random ID. On some pages we have multiple embedded apps and it was working just fine until we started using hooks.

It would only complain on pages that have multiple embedded apps, so the solution was to update the WP shortcode to load the script with the build only once.

Sounds simple and obvious, but it was tricky to figure out! Specially because it was doing that and working fine until we added hooks.

Interestingly enough, on some pages we have other - different - apps that we embed that are also using hooks, and they load their own script/build with React too,... but then it works just fine! The problem was when it was the exact same build being loaded more than once and they use hooks.

What worked for me was a combination of two suggestions from this issue thread.

Main application's webpack config (@apieceofbart's suggestion)

  resolve: {
    alias: {
      react: resolve('./node_modules/react')
    }
  }

Dependency's webpack config (@tsevdos's suggestion)

  externals:
    react: 'react'
  }

I was having this issue with html-webpack-plugin and I was using index.html looks like this as a template to HtmlWebpackPlugin setting.

// webpack.config.js
plugins: [
   new HtmlWebpackPlugin({
      template: "./public/index.html"
   })
],
<!-- public/index.html -->
<html>
<head>
    <title>React App</title>
</head>
<body>
    <div id="root"></div>
    <script src="main.js"></script>
</body>

</html>

I realized the plugin was injecting <script type="text/javascript" src="main.js"></script> right after <div id="root"></div>.

So, when I opened the dev tool and generated html looked like this.

<html>
<head>
    <title>React App</title>
</head>
<body>
    <div id="root"></div>
    <script src="main.js"></script>
    <script type="text/javascript" src="main.js"></script> <!-- injected from html-webpack-plugin -->
</body>

</html>

For me, that was causing Invalid Hook Call Warning.

I was able to remove warning by removing <script src="main.js"></script> like below.

<!-- public/index.html -->
<html>
<head>
    <title>React App</title>
</head>
<body>
    <div id="root"></div>
</body>

</html>

I hope it helps someone looking for a solution!

Be aware that React-dependent libraries can also cause these issues. In my case, I was using different versions of @emotion/core and @emotion/styled.

https://github.com/emotion-js/emotion/issues/1470

Hi,

A possible solution without ejecting is mixing the webpack alias configuration solution with customize-cra and react-app-rewired libraries. This way you can override just the necessary webpack configuration to solve the problem, by creating a config-overrides.js file with:

const { override, addWebpackAlias } = require('customize-cra');
const path = require('path');

module.exports = override(
  addWebpackAlias({
    react: path.resolve(path.join(__dirname, './node_modules/react')),
  }),
);

I had this issue on a Gatsby site, I ran npm install and updated to the latest version of Gatsby and it fixed it all

If you are having an issue with jest testing running yarn or npm test (like I was) and are using react-test-renderer, make sure react-test-renderer matches the same version of react you are using.

Example:

// Package.json
{
  ...
    "react" : "16.8.3",
  ...
}

Run yarn add [email protected]

I have a lib and i checked all versions of react and react-dom in both lib and main projects. they are exact the same but didn't work.
However @apieceofbart solution worked for me.

@apieceofbart , you saved my day <3

What worked for me was a combination of two suggestions from this issue thread.

Main application's webpack config (@apieceofbart's suggestion)

  resolve: {
    alias: {
      react: resolve('./node_modules/react')
    }
  }

Dependency's webpack config (@tsevdos's suggestion)

  externals:
    react: 'react'
  }

Same here. I need to do both of these fixes to make it work. My explanation is that the second config tells the dependency to use external react with the name 'react', and the first config points the name 'react' to the 'node_modules/react' folder in the main repository. Therefore, both of them are necessary to make the react bridge work.

Still, it seems that for some people one of them is enough, which I don't really understand.

What worked for me was a combination of two suggestions from this issue thread.
Main application's webpack config (@apieceofbart's suggestion)

  resolve: {
    alias: {
      react: resolve('./node_modules/react')
    }
  }

Dependency's webpack config (@tsevdos's suggestion)

  externals:
    react: 'react'
  }

Same here. I need to do both of these fixes to make it work. My explanation is that the second config tells the dependency to use external react with the name 'react', and the first config points the name 'react' to the 'node_modules/react' folder in the main repository. Therefore, both of them are necessary to make the react bridge work.

Still, it seems that for some people one of them is enough, which I don't really understand.

The second item is important!
If ignored, on the build process, the react will be exported together, because it's an internal dependency

much love @apieceofbart !!!! I was about to kick my desk through the wall

So, there is still no workaround for microservices. I have root application with react that dynamically requires bundles with another react. We can't just use external version of react because there are a lot of independent teams with their own dependencies. If we push 'em to use same external version then most projects obviously will crash and it will become impossible to upgrade this version due each project will depend on this version.

Any ideas?

Is there a solution for using react hooks together with npm link, that doesn't require ejecting from CRA?

@tschellenbach
you can use craco to overwrite CRA config without eject.
https://github.com/gsoft-inc/craco

Thanks to @tsevdos I've resolved my issue and made a tutorial on how to create a React package: https://youtu.be/esyS87NfBOw

I was getting this issue and the webpack solution didn't apply because I am using parcel bundler instead. I was able to fix it by specifying an alias in the package.json of my main app that looked like this

    "alias": {
        "react": "./node_modules/react",
        "react-dom": "./node_modules/react-dom"
    },

Getting issues with trying to use my React components (written in hooks) in an electron app in the same project with different package json. The file structure looks like this:

- javascript
  - src
     - ComponentIWantToUse.tsx
      - package.json
- electron
   - src
     - IwantToUseItHere.tsx
      - package.json

Both package.json include react and react-dom in package.json but they're the same versions and I'm not seeing it show two react installs when I do npm ls react. Any ideas?

EDIT: @ewan-m 's solution worked!

So I've run into a weird case, I think. A third party library has unfortunately mixed functional and class based components. My components in my codebase are functional. A class based component from the library acts as a layout that renders my component as a child. This I believe is what is triggering the 'Error: Invalid hook call.' How should I work around that to use hooks, do I need to convert mine to a class component?

@GrandathePanda Mixing classes and functional components shouldn't matter. If a class calls a functional, which calls a hook, there's no problem there. The only thing you can't do is call a hook directly from the class.

Okay, @JeremyGrieshop then I still have some investigation to do, if I render without using the third party component it renders fine so there is some conflict between that library and my code then. If I had to guess they are using a different react version maybe in their package.

Okay, @JeremyGrieshop then I still have some investigation to do, if I render without using the third party component it renders fine so there is some conflict between that library and my code then. If I had to guess they are using a different react version maybe in their package.

Right, check npm ls react react-dom from your app to see if there are multiple versions. It's possible the third-party library has a dependency with a specific version.

@JeremyGrieshop So it looks like my application is using 16.12.0 for react and dom and the third-party (elastic search-ui) uses 16.8.0 for react and dom. If I am correct the issue is then that since my 16.8.0 third-party library is rendering the component created with 16.12.0 this will cause the issue? They are also a lerna monorepo which potentially complicates this even further after reading through all of the above comments. The issue is arising from a useStyles hook created in materialui, they supply a withStyles hoc for backwards compatibility and I think in the meantime I'm going to go that route. All the changes to webpack and or the package json mentioned above really seem like a bandaid that is more liable to break then just going with a classic hoc in the meantime while hooks figure out how to mature in the face of so many different implementation quibbles.

@GrandathePanda IMHO, your options are to (1) get the third-party to either update their react dependency to 16.12, or have them decide if having it as a peerDependency is more suitable than a dependency; (2) Use 16.8 in your app so they share same lib versions; (3) Eliminate their copy of react with:

rimraf node_modules/search-ui/node_modules/react && rimraf node_modules/search-ui/node_modules/react-dom

The above command can be placed in a "prebuild" and "prestart" under the "scripts" part of your package.json (which is what I"m currently doing). The downside to (3), I suppose, is if they are using anything deprecated between 16.8 and 16.12.

Hi all,

I have an app (myApp) that uses as dependency a custom library (myDepPackage). Both of them are using webpack as a build tool and of course I was having the same error. None of the above solutions worked for me. What it did, was to force webpack NOT to include react into the final bundle of the custom library (myDepPackage). The only configuration line I had to add to the webpack config (of the myDepPackage) is the below:

externals: {
  react: "react",
},

You can learn more about the "externals" option here: https://webpack.js.org/configuration/externals/#externals

@tsevdos I love you. You just put an end to some days of intense hassle. Thank you.

Hi everyone,

I'm trying to use a hook in a component, this component is to be exported from gatsby-browser.js.

What is the current behaviour?

I am getting this error:

Unhandled Rejection (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
    See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.

This is a sample code:

import React from 'react';
import PropTypes from 'prop-types';
import { Provider } from 'react-redux';

import configureStore from './src/utils/configure-store';
import { useApiResources } from './src/hooks/use-api-resources';

const RootWrapper = ({ element }) => {
  const resources = useApiResources();
  const store = configureStore();
  return <Provider store={store}>{element}</Provider>;
};

RootWrapper.propTypes = {
  element: PropTypes.node.isRequired,
};

export default RootWrapper;

What is the expected behaviour?

Hook should run without errors, or useful error messages should be provided.

Versions of the react and react-dom depencies are 16.12.0

@leejh3224 thanks a lot dude! after hours of searching I found this answer, It solved my problem.
Just changed the HtmlWebpackPlugin config from
inject: true to inject: 'head' and the minified react errors are gone.

I have created a stackoverflow question with my experience of trying to get this to work. Would it be possible, for those who have managed to get this to work, to give it a look and offer some advice?

I'm porting a jquery application to React. I have a utility to expose React components within jQuery called asJqueryPlugin. Here is the file:

import React from 'react'
import ReactDOM from 'react-dom'

/**
 * A way to render React components with props easily with jQuery
 *
 * ## Register the React Component
 *
 * In your React Component file, register the component with jQuery using `asJqueryPlugin`
 * ```
 * const Greeting = ({ person }) => <div>Hello {person}</div>
 * asJqueryPlugin('Greeting', Greeting, { person: "Bob" })
 * ```
 *
 * ## Rendering, Selecting and Updating Props with jQuery
 *
 * Select an element and render using the `react` function
 * ```
 * $('#greeting').react('Greeting', { person: 'Frank' })
 * ```
 */

window.reactRegistry = window.reactRegistry || {}

// This is how React components register themselves as available within jQuery
export default function asJqueryPlugin(componentName, Component) {
  window.reactRegistry[componentName] = { Component }
}

if (typeof window.$ !== 'undefined') {
  ;(function($) {
    // Add the plugin function jQuery
    $.fn.react = function renderReactIntoElements(componentName, props) {
      this.each(function render() {
        const entry = window.reactRegistry[componentName || $(this).data('react')]
        if (!entry) throw Error(`${componentName} component is not registered.`)
        ReactDOM.render(<entry.Component {...props} />, this)
      })
      return this
    }
  })(window.$)
}

The app has many entry points in Webpack, and about 3-4 components are using this technique now. When components are bundled into different entrypoint bundles, I believe that's when the issue happens.

So if I have two entrypoints in Webpack:

entry: {
      foo: './assets/js/foo',
      bar: './assets/js/bar'
}

Then in each of those files we set up an exposed Component (each using hooks):

// foo.js
import React from 'react'
import asJqueryPlugin from '../utils/asJqueryPlugin'
const Foo = () => {
  const ref = useRef()
  return <div ref={ref}>Foo</div>
}
asJqueryPlugin('Foo', Foo)

// bar.js
... same stuff but with Bar component

Now if I include both entries on the same page, and try to render both components via the jquery plugin...

<script src="/bundles/foo.js" />
<script src="/bundles/bar.js" />
<script>
    $('#foo-container').react('Foo')
    $('#bar-container').react('Bar')
</script>

...I get this hooks error.

Not sure if this helps the conversation or not, but at least shows a use case of how a (questionably) sane dev might get themselves into a situation with multiple react instances.

That helped me - https://github.com/facebook/react/issues/13991#issuecomment-554928373
But I also had to remove react and react-dom from the dependencies and move them to peer dependencies and uninstall and reinstall node modules.

Hi,
I read the conversation and many posts on the web and I m still stuck with the error multiple instances of react.
I push this repo for reproduce the bug : https://github.com/jeromelegrand/dooliz-lib
I hope someone can help me.
Thanks.

Im facing this issue and don't get anywhere with solutions above.
In short: I am very certain I have only one react version running, and I get the error using react-bootstrap, which probably doesn't use hooks wrong, because noone else has issues.

This error occurs on a node.js backend for me.

__What I checked around react versions__

I have a yarn setup with workspaces, yarn list react or yarn list react-dom only shows one instance.

I've printed require cache to see what has been imported :

for(var key in require.cache) {
    if(key.indexOf("react") !== -1 && key.indexOf("index") !== -1) {
        console.log(key);
    }
}

I run it just before rending something from react-bootstrap, which causes the invalid hook error for me, and it logs:

C:\web\resourceful\daCore\node_modules\react-dom\index.js
C:\web\resourceful\daCore\node_modules\react\index.js
C:\web\resourceful\daCore\node_modules\react-router-dom\index.js
C:\web\resourceful\daCore\node_modules\react-router-dom\node_modules\react-router\index.js
C:\web\resourceful\daCore\node_modules\react-is\index.js
C:\web\resourceful\daCore\node_modules\mini-create-react-context\dist\cjs\index.js
C:\web\resourceful\daCore\node_modules\react-router\index.js
C:\web\resourceful\daCore\node_modules\@fortawesome\react-fontawesome\index.js
C:\web\resourceful\daCore\node_modules\@tinymce\tinymce-react\lib\cjs\main\ts\index.js

Which seems to confirm that there is only 1 react version loaded.

Finally I've added this to node_modules/react-dom/index.js

console.log("React DOM daCore");
global['React1'] = require('react');

And this to node_modules/react-router-dom/cjs/Form.js

require('react-dom');
global['React2'] = require('react');
console.log('#TEST '+(global['React1'] === global['React2']? 'SAME' : 'NOT SAME'));

Which prints SAME

Any idea what else this can be?
I will also post this on react-bootstrap repo.

So I'm pretty sure that having two instances of React is not the issue here. I think the issue is when there are two react _roots_. Are you calling ReactDOM.render() multiple times into different parts of the page? If so, I think this can cause the issue. I think hooks "belong" to a particular "root" and break when there are multiple of them and the two bundles share some common code. I'm guessing here...

... I think the issue is when there are two react _roots_. Are you calling ReactDOM.render() multiple times into different parts of the page?

Thank you @timkindberg this helped me finaly resolve it. I realised I'm using react-tree-walker to do an initial render and fetch required data before making the final render with ReactDOMServer.renderToString

Quickly removing the use of this package removed the error, and I've now got the same thing working with react-ssr-prepass , which is actually now recommended on the react-tree-walker readme page

So it was indeed two ReactDOM.render calls! For now this setup with react-ssr-prepass works for me, and when Suspense lands in react-dom/server I can switch to that

I'm using react-compare-image https://github.com/junkboy0315/react-compare-image in my Gutenberg project but having this strange issue though everything works whenever I remove the ReactCompareImage component from save function. Edit function works perfectly but the save not working.

I went through https://reactjs.org/warnings/invalid-hook-call-warning.html and I don't think, I've any of these issues.

Here is complete save function file:

```import Inspector from "./inspector";
import { Fragment } from "react";
import ReactCompareImage from "react-compare-image";

/**

  • WordPress dependencies
    */
    const {__} = wp.i18n;

const save = ({className, attributes}) => {

const {
    paddingTop,
    paddingRight,
    paddingBottom,
    paddingLeft,

    marginTop,
    marginRight,
    marginBottom,
    marginLeft,

    border,
    borderColor,
    borderType,
    background,

    backgroundImage,
    gradient,

    dividerColor,
    buttonColor,

    direction,

    beforeImage,
    beforeLabel,
    afterImage,
    afterLabel,

} = attributes;

const style = {
    "padding": `${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`,
    "margin": `${marginTop}px ${marginRight}px ${marginBottom}px ${marginLeft}px`,
    "border": `${border}px ${borderType} ${borderColor}`,
    "background": background
};

return(
    <Fragment>
        <ReactCompareImage
            leftImage={beforeImage.url}
            leftImageLabel={beforeLabel}
            rightImage={afterImage.url}
            rightImageLabel={afterLabel}
            vertical={'vertical' === direction}
            sliderLineColor={dividerColor}
        />
    </Fragment>
);

};

export default save;
```
Screenshot 2020-02-19 at 4 11 52 PM

My Main app is a create-react app (not ejected) that was importing a shared library that also used React. I was able to resolve this by:

Using Rollup to package the library instead of webpack
For some reason I've yet to work out, using externals did not remove React from the library bundle.

rollup-config.js

export default [
  {
    input: 'src/index.js',
    output: {
      file: pkg.main,
      format: 'cjs',
      sourcemap: true,
    },
    plugins: [external(), babel(), resolve(), commonjs(), svgr()],
  },
  {
    input: 'src/index.js',
    output: {
      file: pkg.module,
      format: 'es',
      sourcemap: true,
    },
    plugins: [
      alias({
        entries: [{ find: '@components', replacement: 'src/components' }],
      }),
      external(),
      babel(),
      svgr(),
    ],
  },
]

Installing craco and using that to modify webpack of main app
craco.config.js

const path = require('path')

module.exports = {
  webpack: {
    alias: {
      react: path.resolve(__dirname, './node_modules/react'),
    },
  },
}

Thanks to @arminyahya for pointing me to craco.

I'm trying to use hooks while loading react from a cdn. This example (this is the entire html page) gives the Hooks can only be called inside of the body of a function component error when Example() is called. I've removed everything, even ReactDOM, so it's hard to imagine that I could have multiple copies of React. Is this just impossible?

<!DOCTYPE html>
<html>

<head>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>

</body>
  <script type="text/babel">
    function Example() {
      let [count, setCount] = React.useState(0);
      return ( <h1>Hello</h1> );
    };

  Example();
  </script>
</body>

</html>

@samkamin That's because you have ZERO react roots. You need to render your application. However, this is still a good confirmation that hooks rely on (and are coupled to) a react root.

<html>
<head>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
  <script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
</body>
  <div id="root"></div>
  <script type="text/babel">
    function Example() {
      let [count, setCount] = React.useState(0);
      return ( <h1>Hello</h1> );
    };

    ReactDOM.render(<Example />, document.getElementById('root'))
  </script>
</body>
</html>

Thank you! It actually wasn't the lack of a react root - I just removed that in the course of simplifying the error as much as possible - but something equally dumb: Instead of <Example />, I was just write Example(). Not the same thing, at all. Thanks again.

Nothing seems to work for me. I am creating a component for share and use in other projects, but when testing locally from another project does not work. I'm using Hooks with react 16.13.0.

webpack.config.js

module.exports = {
  entry: ENTRY,
  output: {
    library: LIBRARY_NAME,
    path: path.resolve(__dirname, OUTPUT_DIR),
    filename: OUTPUT_FILENAME,
    libraryTarget: 'commonjs2',
  },
  module: {
    rules: [
      {
        test: /\.(js|tsx)$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: 'ts-loader',
      },
    ],
  },
  resolve: {
    alias: {
      '@src': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components'),
      '@core': path.resolve(__dirname, './src/core'),
      react: path.resolve(__dirname, './node_modules/react'),
      'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
    },
    extensions: ['.js', '.json', '.tsx', '.ts'],
  },
  externals: {
    react: 'react',
  },
  target: 'node',
  plugins: [
    new HtmlWebPackPlugin({
      template: './tests/index.html',
      filename: 'index.html',
    }),
  ]}

Any suggestions? I tested all the suggestions of old discussions.
Thanks! :grin:

I declared a Settings.js as follows:

import React, {useState} from 'react';

import {
    View,
    Text,
    Switch
} from 'react-native';

export function Settings(props) {
    const [rememberPin, setRememberPin] = useState(false);
    let {changeView, header} = props;


    const toggleRememberPin = (value) => {
        setRememberPin(value);
    };

    return (
            <View>
                    <Text>Remember PIN:</Text>
                    <Switch
                        onValueChange={toggleRememberPin}
                        value={rememberPin}
                        ios_backgroundColor="#aeaeae"
                        />
            </View>
    );
}

export default {Settings};

I import and use it in App.js as follows:

import React, {Component} from 'react';
import {
    SafeAreaView,
    StyleSheet,
    View,
    Text,
    TouchableOpacity,
    Dimensions,
    ScrollView,
    Switch
} from 'react-native';

import Colors from './src/assets/Colors';
import {Settings} from './src/components/Settings';
...

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = {viewsStack: this.viewsStack};
    }

    viewsStack = {
        SplashScreen: false,
        BindingInstructions: false,
        PinPad: false,
        Qr: false,
        Dashboard: false,
        Authorizations: false,
        Settings: true,
        Browsers: false,
        TransmitSDK: false,
        OTP: false,
    };

    changeView = (newView) => {
        let {viewsStack} = this.state;
        for (let key of Object.keys(viewsStack)) {
            viewsStack[key] = false;
        }
        viewsStack[newView] = true;
        this.setState(viewsStack);
    };

    render() {
        let {viewsStack} = this.state;
        return (
            <SafeAreaView style={styles.safeAreaView}>
                {viewsStack.SplashScreen && (splashScreen())}
                {viewsStack.BindingInstructions && (bindingInstructions({changeView: this.changeView}))}
                {viewsStack.PinPad && (pinPad({message: 'Inserisci un nuovo PIN', changeView: this.changeView}))}
                {viewsStack.Qr && (qr({header: 'QR Binding', message: 'Scansiona il QR dalla tua dashboard\noppure\ninserisci il codice manualmente.', changeView: this.changeView}))}
                {viewsStack.Dashboard && (dashboard({header: 'Profilo Utente', changeView: this.changeView}))}
                {viewsStack.Authorizations && (authorizations({header: 'Autorizzazioni', authorizations: [1, 2, 3, 4, 5, 6], changeView: this.changeView}))}
                {viewsStack.Settings && (Settings({header: 'Impostazioni', changeView: this.changeView}))}
            </SafeAreaView>
        );
    }
};
...

But I get:

Screenshot 2020-02-27 at 22 27 01

I am using:

"react": "16.9.0",
"react-native": "0.61.5"

What's wrong?

You're calling your Settings component as a function and not as a function component.

<Settings header='Impostazioni' changeView={this.changeView} />

Hooks are not allowed inside plain functions, only in function components and the way you're calling it tricks React into thinking that your component is in reality a normal function.

Maybe this will spare someone the headache, if you're using react-router-dom if you pass your component in render like this (not the proper way) it will give Invalid Hook Call Warning
<Route path="/:cuid/:title" render={PostArticle} />

Took me half an hour to know where I went wrong

This may help someone - if you're experiencing this bug after using react-router-dom, check how you've defined your routes. e.g. it should be<Route path={'/upgrade/:plan'} exact children={<Upgrade />} /> while I was doing <Route path={'/upgrade/:plan'} exact children={Upgrade} />

This is especially awkward if you're using ink or pastel to build a CLI (see https://github.com/vadimdemedes/pastel/issues/2). I can't make it a peerDep because I can't ask every user to install React and I can't force them to use a certain version / range of React either.

My team is using Yarn and was getting the Invalid hook call error only in the tests, not in the app. The problem was that react-test-renderer was resolving to a version lower than that of react and react-dom, so we added resolutions in package.json:

"devDependencies": {
    ...
    "react": "16.12.0",
    "react-dom": "16.12.0",
    ...
},
"resolutions": {
    "react-test-renderer": "16.12.0"
}

For people using Gatsby in a subdir, this is a possible solution.

gatsby-node.js:

const path = require('path')
const fromRoot = name => path.resolve(__dirname + '/../node_modules/' + name)

exports.onCreateWebpackConfig = ({ actions }) => actions.setWebpackConfig({
  resolve: {
    alias: {
      'react': fromRoot('react'),
      'react-dom': fromRoot('react-dom'),
    },
  },
})

I have the same problem when executing the npm link command ,there is a problem

Then I used the official solution provided by react to solve this problem

This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.

If A needs to introduce B (A and B are siblings)

  • step 1 (in B)

    • npm link ./../A/node_modules/react

    • npm link

  • step 2 (in A)
    npm link B

it works for me

Even with these answers I'm unsure why I'm getting the error. I have my dependency library linked to my main app and after I got the error I followed the react-docs and linked my dependency library's version of react to my app's react (running npm link <>/webapp/node_modules/react. (even did this with react-dom). When I logged to test if React1 and React2 were the same, it logged true so I wasn't using duplicate versions of React, I was using the same versions of React, and I was using function components. So even though the test logging indicated that I didn't have a duplicate version of React I was still getting the hook error.

But trying this solution as mentioned above fixed that particular bug:

alias: {
        react: path.resolve('./node_modules/react')
 }

So I'm at a loss.

So I'm at a loss.

@orpheus Do you render more than a single react root into the same page? aka do you have more than one ReactDOM.render call on the same page?

Do you render more than a single react root into the same page? aka do you have more than one ReactDOM.render call on the same page?

@timkindberg

I do not. I have my one ReactDOM.render at the root of my app, and the lib module I'm linking is a component library and does not use a ReactDOM.render at all.

edit: I'm doing something akin to:

import React from 'react'
import ReactDOM from 'react-dom'
import Root from './App/Root'

ReactDOM.render(
  <Root />,
  document.getElementById('root')
)

where <Root /> renders something like

const Root = () => {
  return <Provider store={store}>
        <PermissionsProvider>
              <Suspense fallback={null}>
                <Router history={history}>
                  <Routes store={store} />
                </Router>
              </Suspense>
        </PermissionsProvider>
  </Provider>
}

PermissionsProvider is the React component that I import from my linked lib module that uses a hook which causes the app to fail. It creates state and context and renders it's children.

Hi, I'm using electron with react hooks. if I write my own hook, it' works. But it throw error when I use hooks from other package in node_module, like react-use, swr.

I have to copy package to my local file.

Does anyone meet this problem?

Example project here:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

core code:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

I'm also still having this issue even after removing duplicate copies of react and react-dom. I created a super simple test project to reproduce.

$ tree -I node_modules
.
|-- test-app
|   |-- dist
|   |   |-- index.html
|   |   `-- main.js
|   |-- package-lock.json
|   |-- package.json
|   |-- src
|   |   |-- index.html
|   |   `-- index.js
|   `-- webpack.config.js
`-- test-lib
    |-- dist
    |   `-- main.js
    |-- package-lock.json
    |-- package.json
    |-- src
    |   `-- index.js
    `-- webpack.config.js

Currently, I'm using the webpack alias method, but I've also tried the npm link method, and neither work.

I came across this issue as well. I am using ExpressJS + Pug to render views, I have then written a renderer (similar to ReactRails) that allows you to render components server and client side.

I tried to extract this to a separate package as it was getting messy, and I came across this issue.

In order to fix it, I had to add under the resolve key:

alias: {
  react: path.resolve("./node_modules/react"),
},

It now works as expected when running webpack normally, but the problem still persists with a docker volume. I'm too new to docker to deal with it, so going to revisit it later.

Edit: I spoke too soon. It works fine now with React render, but not with hydrate.

Hi, I'm using electron with react hooks. if I write my own hook, it' works. But it throw error when I use hooks from other package in node_module, like react-use, swr.

I have to copy package to my local file.

Does anyone meet this problem?

Example project here:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error

core code:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hello. I had the same issue. I am using electron-webpack which marks all modules as externals for webpack. With few hardcoded exceptions - like react and react-dom.
For me that meant that react loaded from my code was different than react loaded from such module.
Adding these modules to the whitelist seems to help (not sure if it didn't break anything else yet :)

@huhle thanks, it works! Maybe we should dive into electron-webpack.

I just managed to get this working myself. I think it's one of the better solutions when it comes to Lerna and Yarn workspaces, and maybe some of the pieces could be used for another solution.

It all seems to boil down to the configuration of the package.json project I'm importing. I needed to include these sections:

 "peerDependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "workspaces": {
    "nohoist": [
      "react", "react-dom"
    ]
  }

After doing this, I had to rebuild the projects and I was up and running. It seems that listing them as peer dependencies allows them to be required to be installed by your consuming project. And because they're not listed in dependencies they shouldn't be available to the package you're trying to import, but for some reason unless you tell it not to hoist, they remain available and a new react instance makes its way in and causes the error.

Good luck!

I am trying to use react-spring to get a simple fade-in effect. Nothing seems to be working.
`import React, { useState, useEffect } from 'react';
import { animated, useTransition } from 'react-spring';

const TextContent = (props) => {

const [items] = useState([
    { id: '0', title: 'Text1' },
    { id: '1', title: 'Text2' },
    { id: '2', title: 'Text1' }
])

const [index, setIndex] = useState(0);

const transitions = useTransition(items[index], index => index.id,
    {
        from: { opacity: 0 },
        enter: { opacity: 1 },
        leave: { opacity: 0 },
        config: { tension: 220, friction: 120 }
    }
)

useEffect(() => {
    const interval = setInterval(() => {
        setIndex((state) => (state + 1) % items.length);
    }, 4000)
    return () => clearInterval(interval);
}, []);

return (
    <div>
        {
            transitions.map(({ item, props, key }) => (
                <animated.div
                    key={key}
                    style={{ ...props, position: 'absolute' }}
                >
                    <p>{item.title}</p>
                </animated.div>
            ))
        }
    </div>
)

}

export default TextContent;`
Capture

I tried checking if I have multiple instances of React. Npm ls-ing tells me I just have just a single version of react and react-dom, both of which at 16.13.1.

Hi, I'm using electron with react hooks. if I write my own hook, it' works. But it throw error when I use hooks from other package in node_module, like react-use, swr.
I have to copy package to my local file.
Does anyone meet this problem?
Example project here:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
core code:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hello. I had the same issue. I am using electron-webpack which marks all modules as externals for webpack. With few hardcoded exceptions - like react and react-dom.
For me that meant that react loaded from my code was different than react loaded from such module.
Adding these modules to the whitelist seems to help (not sure if it didn't break anything else yet :)

Brilliant! Thank you

I am trying to use react-spring to get a simple fade-in effect. Nothing seems to be working.
`import React, { useState, useEffect } from 'react';
import { animated, useTransition } from 'react-spring';

const TextContent = (props) => {

const [items] = useState([
    { id: '0', title: 'Text1' },
    { id: '1', title: 'Text2' },
    { id: '2', title: 'Text1' }
])

const [index, setIndex] = useState(0);

const transitions = useTransition(items[index], index => index.id,
    {
        from: { opacity: 0 },
        enter: { opacity: 1 },
        leave: { opacity: 0 },
        config: { tension: 220, friction: 120 }
    }
)

useEffect(() => {
    const interval = setInterval(() => {
        setIndex((state) => (state + 1) % items.length);
    }, 4000)
    return () => clearInterval(interval);
}, []);

return (
    <div>
        {
            transitions.map(({ item, props, key }) => (
                <animated.div
                    key={key}
                    style={{ ...props, position: 'absolute' }}
                >
                    <p>{item.title}</p>
                </animated.div>
            ))
        }
    </div>
)

}

export default TextContent;`
Capture

I tried checking if I have multiple instances of React. Npm ls-ing tells me I just have just a single version of react and react-dom, both of which at 16.13.1.

Same here. react and react-dom are at 16.13.1 for me, and attempting to use react-spring brings this same error.

From another thread over at styled-components, I learned that if you're using a local package of your own through a file: URI in package.json, you need to rm -rf node_modules/local-package-name/node_modules before running your app, because apparently, local packages are copied without checking node_modules for redundant dependencies.

From another thread over at styled-components, I learned that if you're using a local package of your own through a file: URI in package.json, you need to rm -rf node_modules/local-package-name/node_modules before running your app, because apparently, local packages are copied without checking node_modules for redundant dependencies.

Yep, this is the same issue for roughly a dozen use cases in just this thread alone. I added a "prestart" and "prebuild" target to do the rm -rf (using rimraf). Another user in this thread used npm-link-shared in their prestart to get the modules to share the same instance of react. So many of us monorepo users are running into this.

Hi, I'm using electron with react hooks. if I write my own hook, it' works. But it throw error when I use hooks from other package in node_module, like react-use, swr.
I have to copy package to my local file.
Does anyone meet this problem?
Example project here:
https://github.com/Zaynex/electron-react-ts-kit/tree/hooks-error
core code:
https://github.com/Zaynex/electron-react-ts-kit/blob/hooks-error/src/renderer/app.tsx

Hello. I had the same issue. I am using electron-webpack which marks all modules as externals for webpack. With few hardcoded exceptions - like react and react-dom.
For me that meant that react loaded from my code was different than react loaded from such module.
Adding these modules to the whitelist seems to help (not sure if it didn't break anything else yet :)

This also applies for people having trouble with redux or redux toolkit and electron-webpack. I have the following working config:

// package.json
...
"electronWebpack": {
  "whiteListedModules": ["react-redux"]
}

see https://github.com/electron-userland/electron-webpack/issues/349

My issue was that I wrote

import React from 'React'

Instead of:

import React from 'react'

Sometimes it's the dumb things.

I solved it by adding the following to my webpack configuration:

 externals: {
    react: {
      root: "React",
      commonjs2: "react",
      commonjs: "react",
      amd: "react",
    },
    "react-dom": {
      root: "ReactDOM",
      commonjs2: "react-dom",
      commonjs: "react-dom",
      amd: "react-dom",
    },
  },

I initially thought it was a problem with npm link, did all that was suggested, and even switched to yarn. Eventually figured something else was going on when publishing to npm gave the same error when importing in another project.

Has anyone here solved this recently with a lerna monorepo? I've tried a few of the suggestions with no luck.

Running into the error after adding the code that is commented out with the // below. Adding the CssBaseline, and react fragment info causes the error. Everything runs fine when it's commented out. The original code is simply the basic npx create-react-app code. Completely new to this and a few of the fixes I tried from above didn't have an effect.

import React from 'react';
import logo from './logo.svg';
import CssBaseline from '@material-ui/core/CssBaseline';

export default function App() {
return (

        //<React.Fragment>

        //<CssBaseline />

        <div className="App">
            <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                    Edit <code>src/App.js</code> and save to reload.
                    </p>
                <a
                    className="App-link"
                    href="https://reactjs.org"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    Learn React
                    </a>
            </header>
        </div>

    //</React.Fragment>

);
}

For local testing:
In the library node_modules delete the react and react-dom folder
In the main package run "yarn install" or "npm install" again.

This prevents the second copy of react being loaded into the main bundle. Obviously not a permanent fix but works for local testing.

For anyone using lerna, you may come across this problem when running tests in one package, where the code references components in another package.

The problem that we experienced in this case was due to react being imported in the spec, and also being imported in a component in the component tree that was using Material UI's withStyles, which is implemented using hooks in Material UI.

It seems that react internally manages state in a ReactCurrentDispatcher.current variable, and this ends up getting set in one instance of react, but used in the other instance of react -- when it's empty, it throws the Invalid hook call ... message.

We were already using Craco to override Create React App's webpack config at build time:

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

However, this webpack override is only used at build time -- when running the tests, the code isn't built, but instantiated from source -- so our solution was to make use of CracoAlias in our craco.config.js to specify the react path during the tests:

  plugins: [
    {
      plugin: CracoAlias,
      options: {
        source: 'options',
        baseUrl: './',
        aliases: {
          // We need to alias react to the one installed in the desktop/node_modules
          // in order to solve the error "hooks can only be called inside the body of a function component"
          // which is encountered during desktop jest unit tests,
          // described at https://github.com/facebook/react/issues/13991
          // This is caused by two different instances of react being loaded:
          // * the first at packages/desktop/node_modules (for HostSignUpDownloadComponent.spec.js)
          // * the second at packages/components/node_modules (for packages/components/Modal)
          react: './node_modules/react',
        },
      },
    },
  ],

I used @craco/craco as a solution, without ejecting, following the example of @apieceofbart . Steps for me were the following using npm link to get local module tested:

  1. Install craco to my demo app by running npm i @craco/craco --save
  2. Create configuration file craco.config.js to root where package.json lives in demo app.
  3. Change start, build and test scripts by replacing react-scripts with craco in my demo app.
// craco.config.js
const path = require('path');

module.exports = {
    webpack: {
        alias: {
            react: path.resolve(__dirname, './node_modules/react')
        }
    }
}
// package.json
{
....
"scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },
...
}

edit: I did not even notice that @jasondarwin had the same idea.

Spent the better of a day trying to fixing this issue. Posting my solution here incase it helps anyone.

We are using a monorepo and two packages were importing different instances from react, but they were resolving to the same place in the root node modules. Turns out we had these two instances because one of the apps was using it's own webpack to create a bundle. This was correctly being hoisted to the root node module, but would get it's own instance when imported by that package. The solution was include react and react DOM in the externals of the webpack config so that webpack wouldn't create a new instance of react for the bundle.

externals: { react: 'react', reactDOM: 'react-dom', },

Hope this helps someone!

For me it was using react-hot-loader version 4.0.0, updating to react-hot-loader 4.8 seems to do the trick

I'm receiving the Invalid hook call message ONLY when running my tests on a custom Hook that I am creating for working with Modal windows.

To demonstrate the behavior, I have created an example in the following:
(https://github.com/BradCandell/invalid-hook-example)

  • Only one version of react and react-dom

Am I missing something terribly obvious? When I've broken the rule in the past, the npm start would fail. But this is only failing in my tests.

I appreciate the help!
-Brad

I solved it by adding the following to my webpack configuration:

 externals: {
    react: {
      root: "React",
      commonjs2: "react",
      commonjs: "react",
      amd: "react",
    },
    "react-dom": {
      root: "ReactDOM",
      commonjs2: "react-dom",
      commonjs: "react-dom",
      amd: "react-dom",
    },
  },

I initially thought it was a problem with npm link, did all that was suggested, and even switched to yarn. Eventually figured something else was going on when publishing to npm gave the same error when importing in another project.

This fixed it for me. I was importing react-toastify and was getting the invalid hook call. I went through each item in the console error:

  1. You might have mismatching versions of React and React DOM.

    1. You might be breaking the Rules of Hooks.

    2. You might have more than one copy of React in the same app.

Ended up being 3rd issue. I followed this:
https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react

None of the solutions above worked for me, until I realized that I was bundling another copy of react with the library I was _importing_.
I had transpiled and bundled the source code of my library, so the check for different versions of React listed on the docs was returning true instead of false.
Marking react as an external dependency and leaving it out of the bundle of my library did the trick.

My case was not a monorepo, but somewhat similar situation. We are developing a new UI framework, and instead of using npm link or lerna we just use webpack aliases to require the files on a sibling folder. It works fine, but you will run into this problem. Luckily the solution from @apieceofbart fixed the issue for us.

Line 130:21: React Hook "useStyles" is called in function "pharmacyDashboard" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks
Line 133:45: React Hook "React.useState" is called in function "pharmacyDashboard" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks

this is the error.....can anyone please help me in resolving this

@vyshnaviryali you better call your function usePharmacyDashboard

./src/components/HomeFiles/AppFooter.js
Line 1:1: Definition for rule 'material-ui/no-hardcoded-labels'' was not found material-ui/no-hardcoded-labels'
can anyone please help me in resolving this

For everyone who are running this issue with npm link because you need to add features to your component(s) but not wanting to npm publish before testing, I'm surprised nobody suggested using yalc (https://www.npmjs.com/package/yalc)

For everyone who are running this issue with npm link because you need to add features to your component(s) but not wanting to npm publish before testing, I'm surprised nobody suggested using yalc (https://www.npmjs.com/package/yalc)

I actually did last year: https://github.com/facebook/react/issues/13991#issuecomment-535150839

We have been using it for almost a year now without any issues.

Another one here using lerna; to fix this, I moved the react and react-dom dependencies to my root package.json.

I had the same issue and I resolved it by adding:

 alias: {
        react: path.resolve('./node_modules/react')
      }

to resolve property in webpack config of my main app.

It's was obviously my mistake of using two copies of React but I agree that it would be great if the error message was better. I think this is maybe similar to: #2402

For those who are using the method above but still get the errors when running jest, add these to moduleNameMapper in jest's config (omit react-dom if it's not necessary):

moduleNameMapper: {

...

  "^react$": "<rootDir>/node_modules/react",
  "^react-dom$": "<rootDir>/node_modules/react-dom",

...

}

I'm at a loss. I'm getting this but my app doesn't use any hooks and there are no react or react-dom duplicates. I'm using next.js. Could that have something to do with it?

npm ls react
npm ls react-dom

@maapteh was that for me? I did run those commands and didn't find any duplicates. Both libraries are at version 16.13.1

@dancancro I'm also using Next.js and am unable to fix this.

npm ls react and npm ls react-dom both only return one entry. But I'm not sure that's correct. I run into this error when linking to a local package for development. npm ls returns only one entry even when I don't link react in the dependency back to the main repo. But even when I do link react properly, I still get the error.

@justincy I don't have any package links in my project. I'm betting it's related to Next.js. The problem goes away if I put the main component inside a typeof document !== 'undefined', effectively undermining the purpose of Next.js

I managed to fix my problem by deleting react and react-dom from node_modules in the dependency. It's not ideal, but at least I can continue working.

@dancancro I'm skeptical that your problem is caused by Next.js. If it were, lots of other people would have the problem. I'm only running into it because of linked packages. I don't see the error without linked packages.

The problem goes away if I remove five of the seven components in the main component. I can't see anything special about these components. Wrapping these components in typeof document !== 'undefined's works too.

Hi Team, i am trying to upgrade React version from 16.2.0 to 16.13.1, also did the same for react-dom.
Now i am have a wrapper component which is being called at "/test"

class TestWrapper extends React.Component { render() { return ( <React.Fragment> <TestComponent /> </React.Fragment> ) } }

in test wrapper i have imported a functional component with a hook
function TestComponent(props) { useEffect(() => { console.log("TEST COMPONENT"); }); return ( <div> Hello world! </div> ) }

But when the page renders UseEffect hook does not work and Error occurs i.e. Invalid Hook Call Warning
PS. :

  1. I have checked that i have only one copy of react and react-dom is installed
  2. React and react-dom version is 16.13.1

That's what I have
I just ...
@ @
ReactError
I use nextJS so it don't need React importing. And I tried it - don't help.

All other pages and func's working perfectly

@Brotipok what version of next.js? (Seeing simliar problems, but only when moving to 9.5 from 9.4.X)

Hi!

I’ve go the same error , only one package for react and react dom when I do npm ls .

React version : 16.13.1
React-dom version : 16.13.1

I’m using typescript and I have initialized the project with create-react-app my-app --template typescript.

Functional component are only working if I’am not using hooks within it.

Package.json

{
"name": "blablamovie",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@types/jest": "^24.9.1",
"@types/node": "^12.12.53",
"@types/react": "^16.9.43",
"@types/react-dom": "^16.9.8",
"@types/react-router-dom": "^5.1.5",
"react-icons": "^3.10.0",
"react-scripts": "3.4.1",
"typescript": "^3.7.5",
"webpack-bundle-analyzer": "^3.8.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"analyze": "source-map-explorer 'build/static/js/*.js'"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
I'ts an important project and It's turning me a little bit crazy.
If someone can help It would be great.
Thanks.

@Brotipok what version of next.js? (Seeing simliar problems, but only when moving to 9.5 from 9.4.X)

Here's dependencies
"dependencies": {
"next": "9.4.4",
"next-images": "^1.4.0",
"node-sass": "^4.14.1",
"react": "16.13.1",
"react-document-meta": "^3.0.0-beta.2",
"react-dom": "16.13.1",
"react-horizontal-timeline": "^1.5.3",
"react-meta-tags": "^0.7.4",
"react-onclickoutside": "^6.9.0"
},
"devDependencies": {
"@types/node": "^14.0.23",
"@types/react": "^16.9.43",
"typescript": "^3.9.7"
}

I'm running into this same issue when importing material-ui/core/Dialog components, I've set my package.json to use react 16.8.0 specifically for both react and react-dom imports.

I've ran npm ls react and npm ls react-dom with only one import I've also tried the test described in the error page:

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);

Which returns false, however how would I track down the "different" react version that is being imported by a dependency?, it seems to only happen when I import the Material UI Dialog component, it happens as soon as tap a button that triggers it for rendering. I'm able to use other components such as List and ListItems, etc.

I tried forcing resolutions and it didn't fix it either.

I'm not using web pack (really small project) so the build happens with react-scripts build if that makes a difference.

Rewrite: I'll just replace my question with a solution reference (and maybe a request for even more term clarity in the docs, for us dummies? :) )

Background:
I was trying to webpack-compile a functional component with hooks into an asset that where that component could be called from vanilla JS in the browser.

For example,

function Example() {
    const [count, setCount] = React.useState(0);

    return <button onClick={() => setCount(count + 1)}>
        You clicked {count} times
    </button>;
}
export default Example;

...which I wanted to be exported as a module in itself, and after loading that asset, use it directly from HTML, similar to:

<script defer>
            ReactDOM.render(
                ExportedCompiledExample.default(props),
                document.getElementById("my_element")
            );
</script>

I got this working a long time ago _as long as the component didn't contain hooks_. But when using hooks I kept running into this dreaded error message.

The table-flippingly simple solution
I followed _a lot_ of more complicated red herrings (multiple react/reactDOM versions/instances, npm imports and hidden secondary dependencies, react-hot-loader, webpack setup, externals, different bundle/module/library conventions, post-compilation structure...) before trying this, which worked:

export default () => <Example />;

(or export default props => <Example {...props} /> where applicable).

In retrospective 20/20 it makes sense, I guess.

But just to pinpoint the source of confusion in case someone else needs it: the rules-of-hooks docs say _Call them at the top level in the body of a function component_. Which I thought I did, since I actually pasted the example directly into my structure.

My interpretation is that this, from the examples...

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

...is NOT a function component in itself? It becomes so in the right calling context (so, not Example() but <Example />).

I guess I may have missed it somewhere else in the docs, but in case not: it would have saved me a lot of time if a bit of usage context (or just a ES module setup) was included/mentioned/linked to. :) Especially since the direct export default Example version works without hooks.

Thanks for a working solution @apieceofbart! My issue was related to npm link.

Here's how I got it working with Create React App, where the Webpack config is hidden by design. It might be your solution too @florianzemma?

  1. npm install -D react-app-rewired
  2. Create a file called config-overrides.js in your in your project root.
// config-overrides.js
module.exports = function override(config, env) {
  const path = require('path');

  return {
    ...config,
    resolve: {
      ...config.resolve,
      alias: {
        ...config.resolve.alias,
        react: path.resolve('./node_modules/react')
      }
    }
  };
}
  1. Replace relevant react-scripts ... -commands in package.json with react-app-rewired ....

I hope it helps

I got this error because I loaded the bundles 2 times .
In my case it happened because the nunjucks template where script tags were rendered has been used 2 times - in layout itself, and in general template for head tag content,

Yarn workaround

I'm using Yarn, and fixed this by forcing resolution in my package.json:

  "resolutions": {
    "**/react": "16.7.0-alpha.2",
    "**/react-dom": "16.7.0-alpha.2"
  },

Besides adding the resolution in the parent app (consuming library) I updated the library dependencies with the following commands:

  1. yarn add link:/path/to/parent-app/node_modules/react
  2. yarn add link:/path/to/parent-app/node_modules/react-dom

After this I re-linked the library at the parent app with yarn add link:/path/to/library

Hi
I am coming across the same problem with yarn workspaces.
I have a layout like this:

workspace/
├── library/
├── app1/
├── app2/

app1 and app2 have direct dependencies to react v16.9.0, react-dom v16.9.0 and 'library'.
'library' has a peer dependency to react v16.9.0 but also a dev dependency on storybook.
The problem seems to come from storybook which has a dependency on react v16.13.1.
However, when I run yarn install, I end up with with react 16.13.1 in my top level node_modules and react 16.9.0 in the local node_modules of app1 and app2.

When I run app1 (created with CRA), it is using its local react v16.9.0, but the components from 'library' are using React v16.13.1

This seems to me to be a problem with yarn hoisting logic, create-react-apps' webpack definition or both?
Anyone have any idea of a workaround for this scenario?

Hi
I am coming across the same problem with yarn workspaces.
I have a layout like this:

workspace/
├── library/
├── app1/
├── app2/

app1 and app2 have direct dependencies to react v16.9.0, react-dom v16.9.0 and 'library'.
'library' has a peer dependency to react v16.9.0 but also a dev dependency on storybook.
The problem seems to come from storybook which has a dependency on react v16.13.1.
However, when I run yarn install, I end up with with react 16.13.1 in my top level node_modules and react 16.9.0 in the local node_modules of app1 and app2.

When I run app1 (created with CRA), it is using its local react v16.9.0, but the components from 'library' are using React v16.13.1

This seems to me to be a problem with yarn hoisting logic, create-react-apps' webpack definition or both?
Anyone have any idea of a workaround for this scenario?

The only solution I found for this was to yarn run eject the CRA app and switch the order of the resolve section from:

```javascript
modules: ['node_modules', paths.appNodeModules].concat(
modules.additionalModulePaths || []
),
````

to
```javascript
modules: [paths.appNodeModules, 'node_modules'].concat(
modules.additionalModulePaths || []
),
````

It seems strange to me that the 'appNodeModules' is not highest priority - surely the actual app in question should be deferred to when it comes to resolving dependencies?

I encountered the 'hooks' problem in a setting involving Webpack and Electron. My project has a dependency on a module A that is itself bundled by Webpack (and that I authored myself). I externalised React from A (declaring it to be a commonjs2 module). This excludes the React files from the library bundle.

My main program, running in the Electron Renderer process, uses React as well. I had Webpack include React into the bundle (no special configuration).

However, this produced the 'hooks' problem because of two instances of React in the runtime environment.

This is caused by these facts:

  • module A 'requires' React and this is resolved by the module system of Electron. So Electron takes React from node_modules;
  • the main program relies on the Webpack runtime to 'load' React from the bundle itself.
  • both Electron and the Webpack runtime have their own module cache...

My solution was to externalise React from the main program as well. This way, both the main program and module A get their React from Electron - a single instance in memory.

I tried any number of aliases, but that does not solve the problem as an alias only instructs Webpack where to find the module code. It does nothing with respect to the problem of multiple module caches!

If you run into this problem with a module that you cannot control, find out if and how React is externalised. If it is not externalised, I think you cannot solve this problem in the context of Electron. If it is just externalised as a global, put React into your .html file and make your main program depend on that as well.

Finally...

//webpack.config.js

module.exports = {
  ...
  externals: {
      react: 'react',
  },
}

Vue3 has the same problem

I solved this issue putting react and react-dom as peerDependencies in my package.json of my external library, which uses React.

  "peerDependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },

I guess I may have missed it somewhere else in the docs, but in case not: it would have saved me a lot of time if a bit of usage context (or just a ES module setup) was included/mentioned/linked to. :) Especially since the direct export default Example version works without hooks.

Hi @espen42 ,
I was really hoping your solution will help us. We literally tried _everything_, just like you mentioned.

Unfortunately, your solution does not seem to help either. I wonder maybe I just missed something?

So, in a package (I'll call it @bla/bla), we have the index.js that has a component with hooks, like

function Bla = ({...props]) => {
const [bla, setBla] = useState(false);
return bla ? <div {...props} /> : 'no luck';
}

We compile the package using npx babel.

We link this package with npm link and then include it in the project like npm link @bla/bla.
Both the package and the project use the same version of React and react-dom.

In the project, we include the package like this:

import Bla from `@bla/bla`

const RenderBla = ({...props}) => <Bla {...props} />

export default RenderBla

Unfortunately, the error still persists.
Invalid hook call. Hooks can only be called inside of the body of a function component.

What can we be missing?

"externals": {
  "react": "react",
  "react-dom": "react-dom"
}

This one fixed the issue for me, thank you so much man ❤️

Field Customizer error when accessed via external link (Sharepoint Online)

A spfx field customizer extension with a few fabric ui component, when accessed via link, getting one of these error depending on the fabricUI version:
https://reactjs.org/docs/error-decoder.html/?invariant=321,
https://reactjs.org/docs/error-decoder.html/?invariant=290&args[]=A.%20General

when the page is refreshed, everything works properly.
I haven't used any React Hooks in the code, only React Components.
Haven't used any refs either.

I think it might be because of Fabric ui cause when all fabric ui components are removed, no error occurs.

Have tried different versions of fabic ui, 6.189.2, 6.214.0 and 7.114.1 and also tried replacing all fabric-ui references with fluent ui, still issue persists

checked the react versions, here is the output
npm ls react
+-- @microsoft/[email protected]
| +-- @microsoft/[email protected]
| | -- [email protected] deduped | +-- @microsoft/[email protected] | |-- [email protected] deduped
| +-- @microsoft/[email protected]
| | -- [email protected] deduped |-- [email protected] deduped
`-- [email protected]

Hi all,
i also stumbled upon this annoying error. In my case this was also a miss-configuration of my webpack build in the end. But none of the suggested things in this issue has worked for me. So i want to share my experience as well.

My page includes multiple entry points, and the SplitChunkPlugin can create runtime chunks. Because we are using the rails-webpacker gem it was configured by default to create a runtime for each chunk. But webpack does something similar by default, it includes the runtime inside the chunks.

Of course the documentation warns about this case, but you have to find it. Setting the optimization.runtimeChunk to single will create a seperated runtime. This will prevent your build instantiating multiple copies of react, when using react from multiple entry points.

See https://webpack.js.org/configuration/optimization/#optimizationruntimechunk

Hey everyone,
I have the problem that I want to use an external lib that comes from a CDN and is included with a <script> tag, so there is not much I can do with the code itself. The lib uses react and hooks, so I get the
3. You might have more than one copy of React in the same app error.
Sadly there is no NPM package for the library: https://github.com/Anyline/anyline-ocr-anylinejs-module
Im using CRA and the project is not ejected.

Created a little example Sandbox.

It throws that same error since the other package is also using hooks but with its own React. I had to publish my package to NPM and then import it directly from NPM. That

I come into this issue recently and wonder why.
I solved it by upload it to GitLab and install it by address.
What's the difference between package and local package?

I have found that I get the "Invalid hook call." when I dynamically load the Component that is calling the hook.

Code Sandbox

The test that loads "App" statically passes. The two tests that load it dynamically (one using require, one using import as a function) both give the error.

Why I even care: I'm trying to write some tests where I am using jest.doMock to mock some things out and then dynamically loading the module I want to test, as per the documentation. I'm using doMock instead of Mock because I need to be able to mock things differently in different functions. You'll notice that the error occurs without any mocking involved, though.

It throws that same error since the other package is also using hooks but with its own React. I had to publish my package to NPM and then import it directly from NPM. That

I come into this issue recently and wonder why.
I solved it by upload it to GitLab and install it by address.
What's the difference between package and local package?

@catsheue was React1 === React2 true for you?
i havent had mine published in npm yet wanted to know if thats the cause

mine seems to be React1 === React2 = true and havent found solution why this is happening when im importing my react library into a project

Had this same problem using yarn link to test a local library. My mistake was listing react and react-dom as dev dependencies not peer.

So I should have done yarn add --peer react react-dom. Finally, because I already made the mistake in committing React as a dev dependency, I needed to purge node_modules from my library. rm -rf node_modules; yarn fixed the problem for me.

I too faced this issue. In my case it was caused by a duplicate React from Storybook (v6.0.28). I believe you can find more info here.

I uninstalled Storybook dependencies, deleted node_modules and run yarn install again. This worked for me. I hope it helps someone avoid the tears and wasted hours on this.

This workaround works for me as well. I'm using Firebase Functions and have a node_modules folder in both my project root and under the /functions/ directory. If I delete /functions/node_modules, my app runs fine. This is a workaround, but it is fairly annoying. Has anyone found a workaround that allows for both node_modules folders to exist at the same time?

For posterity and anyone who might be facing this problem when using mdbootstrap in an app created with create-react-app.

I saw this error when adding various mdbootstrap components such as buttons and card images. The console output added to index.js for troubleshooting as per React support article returned true on comparing versions. So I had to try something else.

The fix was to run an npm dedupe

npm ls react

+-- [email protected]
| `-- [email protected]
`-- [email protected]

npm dedupe

npm ls react

+-- [email protected]
| `-- [email protected]  deduped
`-- [email protected]

After this, all components worked just fine. Happy days.

I have found that I get the "Invalid hook call." when I dynamically load the Component that is calling the hook.

Code Sandbox

The test that loads "App" statically passes. The two tests that load it dynamically (one using require, one using import as a function) both give the error.

Why I even care: I'm trying to write some tests where I am using jest.doMock to mock some things out and then dynamically loading the module I want to test, as per the documentation. I'm using doMock instead of Mock because I need to be able to mock things differently in different functions. You'll notice that the error occurs without any mocking involved, though.

@miket01 Exactly what I try to do (but w/o mocking). Did you found any solution?

Encountered this doing:

function HeadedSection (props) {
   if (!ReactDOMServer.renderToStaticMarkup(props.children))
        return null;

    const [hidden, set_hidden] = useState(props.hidden);

Fixed by calling useState first:

function HeadedSection (props) {
    const [hidden, set_hidden] = useState(props.hidden);

    if (!ReactDOMServer.renderToStaticMarkup(props.children))
        return null;

I'm still getting this error after setting it aside for many months.

I use zero hooks in my program. There is exactly one copy of react and one copy of react-dom and they are the same version. There are no links.

It had partly worked before I recently tried to update a few packages to fix security problems. I'm using next.js and the fix was to exclude some subcomponents from the top level component by wrapping them in {typeof window !== 'undefined' but now that doesn't work either.

[18:50:42] (master) questions
// ♥ npm ls react
[email protected] /Users/Dan/work/b/questions
└── [email protected]

[22:46:34] (master) questions
// ♥ npm ls react-dom
[email protected] /Users/Dan/work/b/questions
└── [email protected]

[22:46:55] (master) questions
// ♥ npm dedupe
removed 55 packages, moved 46 packages and audited 1712 packages in 65.449s

33 packages are looking for funding
  run `npm fund` for details

found 26 vulnerabilities (15 low, 3 moderate, 8 high)
  run `npm audit fix` to fix them, or `npm audit` for details

The error is thrown because ReactCurrentDispatcher.current === null but I can't find anywhere in the /node_modules/react/cjs/react.development.js where this is set to something.

Can someone tell me where ReactCurrentDispatcher.current ought to be getting a value?
https://github.com/facebook/react/search?p=2&q=%22ReactCurrentDispatcher.current+%3D%22&type=code

This looks like a candidate, but this code is not contained in my react-development.js. Should it be?

    const prevPartialRenderer = currentPartialRenderer;
    setCurrentPartialRenderer(this);
    const prevDispatcher = ReactCurrentDispatcher.current;
    ReactCurrentDispatcher.current = Dispatcher;

https://github.com/facebook/react/blob/702fad4b1b48ac8f626ed3f35e8f86f5ea728084/packages/react-dom/src/server/ReactPartialRenderer.js#L859

I'm getting this error with server-side rendering by next.js and this code is in the react source under react-dom/server. How can I determine if /node_modules/react/cjs/react-development.js is correct?

UPDATE: This was the problem. I had edited webpack.config.externals in my next.config.js file
https://github.com/vercel/next.js/issues/17592#issuecomment-712443172

My App throws a massive error (invalid hook call) any time i try to integrate material UI into it. I'm completely new to React so i need help.

Was this page helpful?
0 / 5 - 0 ratings