-
Notifications
You must be signed in to change notification settings - Fork 46.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hooks + multiple instances of React #13991
Comments
So just for clarification: You were importing a hook (say 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 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 "prestart": "npm-link-shared ./node_modules/<other package>/node_modules . react" |
I had the same issue and I resolved it by adding:
to 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 |
@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 |
Same issue here when I |
I fixed my issue by removing the caret in |
I'm using Yarn, and fixed this by forcing resolution in my
|
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 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 |
Hello, I also have this issue. I read through the page carefully and checked everything and could not see anything amiss. I have a custom component library in React 18.2.0 and a Project in React 18.2.0. Both use Vite for bundling. I am using serve side rendering with The issue is always occurring if I enable SSR, I don't see it if I only use client side rendering, which makes think that it might be due to that In my library I have created a dummy hook: function testHook() {
console.log('testHook: testHook');
console.log('testHook: React', React);
console.log('testHook: ReactDOM', ReactDOM);
console.log('testHook: testHook');
const [testBool, setTestBool] = useState(false);
useEffect(() => {}, []);
} I am calling this hook in my top level page component: function Page() {
//@ts-ignore
ReactDOM.testNew = 'testNew'; // I can see that this appended in my lib
//@ts-ignore
React.test = 'test'; // I can see that this appended in my lib
const test = testHook();
return <></>;
} I also checked if ./node_modules/react-dom/index.js
if (typeof window !== 'undefined') {
window.React1 = require('react');
}
./page/dummy.tsx
import React from 'react';
import ReactDOM from 'react-dom';
...
if (typeof window === 'undefined') {
return <></>;
}
@ts-ignore
window.React2 = require('react');
@ts-ignore
console.log(window.React1 === React); // true So It seems to me that I am doing everything correctly and still see this issue. I saw that the issue goes away if I do either:
Appendix:I am unsure if this helps but here are also my Vite bundling configs of my lib: /// <reference types="vitest" />
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import dts from 'vite-plugin-dts';
// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, 'src/index.ts'),
formats: ['es', 'cjs'],
name: '@workdigtital/component-library-react',
fileName: (format) => `index.${format}.js`
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM'
},
exports: 'named'
}
}
},
plugins: [react(), dts({ insertTypesEntry: true })],
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./src/tests/setup.ts'],
exclude: ['**/node_modules/**', '**/dist/**', '**/coverage/**', '**.stories**', '.storybook/**', '**.types**'],
coverage: {
all: true,
exclude: ['**/*.stories.tsx', '.storybook/**'],
provider: 'c8',
reporter: ['cobertura', 'html']
}
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@flaticon': path.resolve(__dirname, './node_modules/@flaticon')
}
}
}); Stack Trace:
SolutionMy issue was with a third party plugin https://socket.dev/npm/package/vite-plugin-circular-dependency, removing it helped. |
None of the above solutions worked for me until I upgraded styled-components from v5 to v6. I was even getting If you're using styled-components, try upgrading. |
I am getting "Invalid Hook Call" error for below code
Any help on this would be appreciated |
I'm getting Invalid hook call. I'm using this code from email.js: `const Contact = () => {
I'd appreciate the help |
😪😔 |
I am creating a UI library so I used useState in my library component and when I use this library in my project with npm link library or npm install library I get this error `reactjscomponents.js:2 Uncaught TypeError: Cannot read properties of null (reading 'useState') ` at t.useState (reactjscomponents.js:2:1) my package.json my webpack file module.exports = { my babel file |
I am also getting So I am guessing , it might have to do something with 1. mismatching versions of React and React DOM. or 2.more than one copy of React . In general ,
I am getting any help is appreciated |
This is resolved. The issue here was that I was using two
to
So the issue was never one of these which I was thinking - hooks rules , mismatching versions of React and React DOM , more than one copy of React Or using useNavigate() . They may be an issue in some scenarios but in this particular scenario the issue was using two |
I hit this error today on a component which renders a sub-component and attaches a callback ref to that sub-component. Inside the handler for that callback ref, it was calling a method which eventually called Not sure if integral to the repro, but it also relied on accidentally double-rendering our entire dev page on page load. We were accidentally loading the entire webpack bundle twice, so the first render was getting unmounted and blown away by the second render. It was quite hard to track down and didn't fit the three things listed in the troubleshooting error message. A big part of the difficulty was that the error was being reported from a hooks/function component which was being rendered as a sibling of the aforementioned host component, not a child. |
Hello, I believe I have part of the solution for this error message. This error message can present itself in multiple ways depending on the exact APIs used in your component. I believe it all boils down to React detecting multiple copies of itself, even if they are the exact same version. Issue(s):Warning: 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:
TypeError: Cannot read properties of null (reading 'useState') Solution:
Run your app and hopefully the React error will be resolved! ReproducingThis error can be reproduced with this minimal setup.
I hope this helps some people out there. Thank you! |
Hi there fellow Dev's, I am struggling with this issue to, mine is related to plugin development. I created two functional components for a plugin in WordPress: one called edit (used in the back-end for displaying the plugin in the block editor) and another called RecentPosts (which is supposed to be integrated into edit.js for more functionality). Here's the code for edit:
Here's the code for RecentPosts:
After running my scripts using the command
To solve this problem, I clicked on the link provided in the error which brought me to this page. After clicking on the link provided in the red box, I got to this page. Over there, I found a list and analysis of possible causes of this error, I checked for all of them but it turned out that I didn't make any of the mistakes they referred to or violated the rules for React hooks. I also prompted ChatGPT (3.5), it gave me the following response:
As it seems to me, my code basically looks the same, as you'll see, I am not completely sure what could be causing this error. It only occurs When |
Please help me resolve this problem.
Here is the
The main issue is that I am unable to reproduce the problem. The error appears randomly, once in a few hours, mostly when I reload the page. After it appears, no matter how hard may I try to reproduce it, it would not reappear. I have manually checked all the hooks and they are all directly inside React components. Here is my "use client";
import { createContext, useState } from "react";
const AlertContext = createContext({
alerts: [],
showAlert: () => {},
hideAlert: () => {},
});
const AlertProvider = ({ children }) => {
const [alerts, setAlerts] = useState([]);
const showAlert = ({ type, message }) => {
setAlerts([{ type, message, timestamp: Date.now() }]);
};
const hideAlert = () => {
setAlerts([]);
};
return (
<AlertContext.Provider value={{ alerts, showAlert, hideAlert }}>
{children}
</AlertContext.Provider>
);
};
export { AlertProvider, AlertContext }; Here is my root import { Roboto } from "next/font/google";
import "@/app/globals.css";
import { AlertProvider } from "@/context/AlertContext";
import StoreProvider from "@/store/StoreProvider";
const roboto = Roboto({
subsets: ["latin"],
weight: ["100", "300", "400", "500", "700", "900"],
});
export const metadata = {
title: "title",
description: "description",
};
export default function RootLayout({ children }) {
return (
<>
<StoreProvider>
<AlertProvider>
<html lang="en">
<body className={roboto.className}>{children}</body>
</html>
</AlertProvider>
</StoreProvider>
</>
);
} The versions of react and react-dom are both 18.
I ran the command on my terminal and here is the result: PS C:\Users\user\Desktop\project> npm ls react
project@0.1.0 C:\Users\user\Desktop\project
+-- @reduxjs/toolkit@2.2.3
| `-- react@18.2.0 deduped
+-- next@14.2.1
| +-- react@18.2.0 deduped
| `-- styled-jsx@5.1.1
| `-- react@18.2.0 deduped
+-- react-dom@18.2.0
| `-- react@18.2.0 deduped
+-- react-icons@5.1.0
| `-- react@18.2.0 deduped
+-- react-redux@9.1.1
| +-- react@18.2.0 deduped
| `-- use-sync-external-store@1.2.0
| `-- react@18.2.0 deduped
+-- react-slick@0.30.2
| `-- react@18.2.0 deduped
`-- react@18.2.0 Then it says:
// 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 tried it in my current Next.js project,in a new Next.js project, and in a new React.js project using vite. I have also added
|
I was experiencing this same issue when attempting to use
However, I found this only partially fixed the issue. Because the project I was attempting to link was a react component library that in turn made use of various other react libraries (react-router, ag-grid, @mui/material, etc) I needed to add aliases for all these other dependencies as well for local development (for production, they are all marked as peer dependencies & externals). So my webpack configuration ended up looking more like this:
|
react.development.js:209 Warning: 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:
how to resolve this error |
Sorry to disturb/notify all the followers of this issue, but for anyone coming here with a monorepo setup like npm workspaces, please make sure you don't have react included as dependencies multiple places, and also check any dangling package-lock.json or yarn.lock. I struggled with this issue for a couple of days, and in the end it all came down to a package-lock.json in one of the workspaces that had some react references that I didn't think of. |
If you are implementing a react component library and having this issue, try to include multiple versions in the peerDependencies. "peerDependencies": { |
I was developing a Shopify app and had the same issue. |
Is there way to find out in runtime that application has multiple React instances? |
Here's another way to get this error on Windows specifically. I had it in a Next.js project and in the end it was webpack that had a problem. Anyway, the problem was that I used PowerShell and went to the project directory using commands like Note how it's not capitalized. Windows is case insensitive and will find the directory anyway, and PowerShell doesn't care to check if the casing is right, so it just takes whatever you enter. Indeed, you can just use any casing that you want: As you see, commands such as SolutionEnsure that the path has correct casing. When using commands like when pressing tab turns into ...which is then correct. Or install an "Open PowerShell here" to the right click context menu (can be done using regedit) to avoid having to navigate to your React project in PowerShell at all. |
I have a react.js app which is added to our clients' websites as a widget. The clients' websites can be built on any tool e.g. wordress / angular / react etc. We've two types of widgets On clients' sites we simply add a script and stylesheet of our build's index.js and index.css files hosted on s3. Till this part it works just fine e.g. Here's a sample build we've: In my app we can have multiple grids which are to be lazy loaded based upon the client ( e.g. in the above build you can see the trips grid being lazy loaded ). We need this so that our build size doesn't increase much and on any individual client's site only the grids relevant to that client are loaded. Now this works fine when I include either the Here's an example of loader which is lazy loading trips grids:
Here's a sample trip grid's code:
I get the following error when trips grids ( or any other grids are lazy loaded - also these errors occur happen randomly not always ) I've looked into it and spent hours. As per the documentation here: https://react.dev/errors/321 ( it happens due to incorrect hook calls or react version mismatch errors ).
If I do Note that it also works just fine when I don't lazy load trips grids ( or any other grids ) e.g. like this:
Can anyone please point me to the right direction. |
I'm getting this error when I use the I also always get false from the multiple reacts test. I'm using imports instead of require so not sure if this is right: in react-dom/index.js
In my component
This always gives me false, even if I remove Without With First questing is, do I have 2 reacts or not? Second is why does using [UPDATE] |
In my understanding, two react version is mean there exists something wrong, when functions apply react. But it's not the true problem sometime. The error may caused by wrong module caches, or wrong build config (different module use different react version will cause the issue).
Some time i only need delete all the module caches, and re install modules by force option, and reopen the editor, re-build project again. And the issue fixed.:)
Just my understanding through my own experience, hope can help u.
…---Original---
From: "Jim ***@***.***>
Date: Thu, Oct 24, 2024 02:50 AM
To: ***@***.***>;
Cc: ***@***.******@***.***>;
Subject: Re: [facebook/react] Hooks + multiple instances of React (#13991)
I'm getting this error when I use the getParams hook from react-router-dom. Other hooks work fine like useLocalStorage from @uidotdev/usehooks.
I also always get false from the multiple reacts test. I'm using imports instead of require so not sure if this is right:
in react-dom/index.js
import react from 'react'; window.React1 = react;
In my component
import react from 'react'; window.React2 = react; console.log(window.React1 === window.React2);
This always gives me false, even if I remove react-router-dom. Here is the output of npm ls react:
Without react-router-dom
***@***.*** .../previewer2
├─┬ ***@***.***
│ └── ***@***.*** deduped
└── ***@***.***
With react-router-dom
***@***.*** .../previewer2
├─┬ ***@***.***
│ └── ***@***.*** deduped
├─┬ ***@***.***
│ ├─┬ ***@***.***
│ │ └── ***@***.*** deduped
│ └── ***@***.*** deduped
└── ***@***.***
First questing is, do I have 2 reacts or not? Second is why does using getParams specifically cause this error? Note that I'm not using react-router-dom for anything other than getParams, app is a very simple single page, no routing.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
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.
The text was updated successfully, but these errors were encountered: