I'm using Emotion as the styling library for my own React component library. I've ensured that my projects are using React 18.3.1 for both the react
and react-dom
packages.
Here are the relevant test Emotion dependencies:
{
"@emotion/css": "^11.13.5",
"@emotion/react": "^11.14.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
I ensured the same versions are used in my library.
Using the Parcel bundler to run a test webpage, I get this at the browser console:
Button.tsx:41 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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
This is my Button
component:
import { css } from "@emotion/css";
// [...]
import { ThemeContext } from "../theme";
// [...]
export function Button(options: ButtonOptions)
{
// This is the line 41
const theme = useContext(ThemeContext);
const newStyle: React.CSSProperties = {};
// Ommited newStyle assignments
// [...]
let className: string = "";
const padding = "0.7rem 1rem";
switch (options.variant ?? "secondary")
{
case "secondary":
{
// uses providedTheme.colors.foreground as character color
className = css `
/* CSS here */
`;
break;
}
case "primary":
{
className = css `
/* CSS here */
`;
break;
}
case "danger":
{
className = css `
/* CSS here */
`;
break;
}
case "outline":
{
const dark = Color(theme.colors.background).isDark();
const color = dark ? "#fff" : "#000";
const hoverBg = dark ? "rgba(255, 255, 255, 0.4)" : "rgba(0, 0, 0, 0.4)";
const pressedCharColor = dark ? "#000" : "#fff";
className = css `
/* CSS here */
`;
break;
}
case "outline-primary":
{
const dark = Color(theme.colors.background).isDark();
const color = dark ? "#fff" : "#000";
const bg = dark ? "rgba(255, 255, 255, 0.4)" : "rgba(0, 0, 0, 0.4)";
const hoverBg = dark ? "rgba(255, 255, 255, 0.6)" : "rgba(0, 0, 0, 0.6)";
const pressedCharColor = dark ? "#000" : "#fff";
className = css `
/* CSS here */
`;
break;
}
}
return <button className={className} style={newStyle} type={options.type ?? "button"} disabled={options.disabled ?? false} autoFocus={options.autoFocus ?? false}>{options.children}</button>;
}
Here's ThemeContext
:
// [...]
export const ThemeContext: React.Context<Theme> = createContext(lightTheme);
Tried to reproduce the issue here with no luck (instead works); I am guessing it's the bundler I was using (Parcel), so I tried using Vite instead as in that code snippet, but no luck either, as I get this when the webpage loads:
assert.js?v=00bb3fe6:1843 Uncaught ReferenceError: process is not defined
Here is my package manifest:
{
"name": "demo",
"type": "module",
"devDependencies": {
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"typescript": "~5.7.2",
"vite": "^6.1.0"
},
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@emotion/css": "^11.13.5",
"@emotion/react": "^11.14.0",
"@fontsource/open-sans": "^5.1.1",
"@hydroper/metrocomponents": "file:..",
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
}
I'm using Emotion as the styling library for my own React component library. I've ensured that my projects are using React 18.3.1 for both the react
and react-dom
packages.
Here are the relevant test Emotion dependencies:
{
"@emotion/css": "^11.13.5",
"@emotion/react": "^11.14.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
I ensured the same versions are used in my library.
Using the Parcel bundler to run a test webpage, I get this at the browser console:
Button.tsx:41 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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
This is my Button
component:
import { css } from "@emotion/css";
// [...]
import { ThemeContext } from "../theme";
// [...]
export function Button(options: ButtonOptions)
{
// This is the line 41
const theme = useContext(ThemeContext);
const newStyle: React.CSSProperties = {};
// Ommited newStyle assignments
// [...]
let className: string = "";
const padding = "0.7rem 1rem";
switch (options.variant ?? "secondary")
{
case "secondary":
{
// uses providedTheme.colors.foreground as character color
className = css `
/* CSS here */
`;
break;
}
case "primary":
{
className = css `
/* CSS here */
`;
break;
}
case "danger":
{
className = css `
/* CSS here */
`;
break;
}
case "outline":
{
const dark = Color(theme.colors.background).isDark();
const color = dark ? "#fff" : "#000";
const hoverBg = dark ? "rgba(255, 255, 255, 0.4)" : "rgba(0, 0, 0, 0.4)";
const pressedCharColor = dark ? "#000" : "#fff";
className = css `
/* CSS here */
`;
break;
}
case "outline-primary":
{
const dark = Color(theme.colors.background).isDark();
const color = dark ? "#fff" : "#000";
const bg = dark ? "rgba(255, 255, 255, 0.4)" : "rgba(0, 0, 0, 0.4)";
const hoverBg = dark ? "rgba(255, 255, 255, 0.6)" : "rgba(0, 0, 0, 0.6)";
const pressedCharColor = dark ? "#000" : "#fff";
className = css `
/* CSS here */
`;
break;
}
}
return <button className={className} style={newStyle} type={options.type ?? "button"} disabled={options.disabled ?? false} autoFocus={options.autoFocus ?? false}>{options.children}</button>;
}
Here's ThemeContext
:
// [...]
export const ThemeContext: React.Context<Theme> = createContext(lightTheme);
Tried to reproduce the issue here with no luck (instead works); I am guessing it's the bundler I was using (Parcel), so I tried using Vite instead as in that code snippet, but no luck either, as I get this when the webpage loads:
assert.js?v=00bb3fe6:1843 Uncaught ReferenceError: process is not defined
Here is my package manifest:
{
"name": "demo",
"type": "module",
"devDependencies": {
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"typescript": "~5.7.2",
"vite": "^6.1.0"
},
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@emotion/css": "^11.13.5",
"@emotion/react": "^11.14.0",
"@fontsource/open-sans": "^5.1.1",
"@hydroper/metrocomponents": "file:..",
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
}
Share
Improve this question
edited Feb 17 at 20:39
Matheus Dias de Souza
asked Feb 17 at 15:54
Matheus Dias de SouzaMatheus Dias de Souza
12 bronze badges
1
- this error usually occurs when a hook is inside a conditional. your code looks correct. can you reproduce it on stackblitz or codepen and add a link in your post? – Alp Commented Feb 17 at 19:21
1 Answer
Reset to default 0It was indeed a bug in the Parcel bundler. I have used Vite and then it worked, but it required extra configuration. I have combined the two answers in this question, resulting into this Vite configuration:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
define: {
"process.platform": JSON.stringify(process.platform),
"process.env.IS_PREACT": JSON.stringify("true"),
},
});