Next.js Discord

Discord Forum

Error: invalid hook call using

Answered
Chinese perch posted this in #help-forum
Open in Discord
Avatar
Chinese perchOP
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:
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://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
TypeError: Cannot read properties of null (reading 'useContext')
at useContext (E:\anshu\js3\nextjs-blog\node_modules\react\cjs\react.development.js:1618:21)
at useColorMode (file:///E:/anshu/js3/nextjs-blog/node_modules/@chakra-ui/color-mode/dist/chunk-7NLW6UB6.mjs:6:19)
at eval (webpack-internal:///./pages/_app.js:18:104)
- warn Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/messages/fast-refresh-reload

Happening due to _app.js
import '../styles/global.css';
import { ChakraProvider, IconButton, useColorMode } from '@chakra-ui/react'
import { MoonIcon, SunIcon } from "@chakra-ui/icons";

const { colorMode, toggleColorMode } = useColorMode();

export default function App({ Component, pageProps }) {

  return (
    <ChakraProvider>
      <IconButton
        icon={colorMode === "light" ? <SunIcon /> : <MoonIcon />}
        onClick={toggleColorMode}
        mr={4}
        variant="outline"
      ></IconButton>
      <Component {...pageProps} />
    </ChakraProvider>
  )
}
Answered by maxswjeon
ColorModeButton.js
export default function ColorModeButton() {
  const { colorMode, toggleColorMode } = useColorMode(); // Now the useColorMode will work
  return (    
      <IconButton
        icon={colorMode === "light" ? <SunIcon /> : <MoonIcon />}
        onClick={toggleColorMode}
        mr={4}
        variant="outline"
      />
  )
}


App.js
export default function App({ Component, pageProps }) {
  return (
    <ChakraProvider>
      <ColorModeButton />
      <Component {...pageProps} />
    </ChakraProvider>
  )
}
View full answer

104 Replies

Avatar
Chinese perchOP
I used chakra to try and create a dark mode toggler
const { colorMode, toggleColorMode } = useColorMode();

<IconButton
  icon={colorMode === "light" ? <SunIcon /> : <MoonIcon />}
  onClick={toggleColorMode}
  mr={4}
  variant="outline"
></IconButton>

this itself works
can you possibly explain? I'm new to next
client side rendering?
Avatar
Move
const { colorMode, toggleColorMode } = useColorMode();

Into App
Avatar
sorry nvm, this is pages router...
Avatar
Chinese perchOP
uh.. ok
Avatar
Since useColorMode is a hook and as App is used in there, there is no need to use "use client" here
Yup I think it is too
Avatar
Chinese perchOP
Server Error
TypeError: Cannot read properties of null (reading 'useContext')

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source
pages_app.js (5:51) @ useColorMode
  3 | import { MoonIcon, SunIcon } from "@chakra-ui/icons";
  4 | 
> 5 | const { colorMode, toggleColorMode } = useColorMode();
    |                                                 ^
  6 | 
  7 | export default function App({ Component, pageProps }) {
  8 | const { colorMode, toggleColorMode } = useColorMode();
I had tried that before too. error is above
Avatar
Oh I see
Avatar
Chinese perchOP
oh wait
Wait
Avatar
so the useColorMode should be inside the ChakraProvider
Okay
Avatar
Chinese perchOP
My bad
my bad
The page now loads, but the button does not work
Avatar
So how did you moved the useColorMode now?
I think the Button should be a seperate component in seperate file
Avatar
Chinese perchOP
same as you said
export default function App({ Component, pageProps }) {
  const { colorMode, toggleColorMode } = useColorMode();

  return (
    <ChakraProvider>
      <IconButton
        icon={colorMode === "light" ? <SunIcon /> : <MoonIcon />}
        onClick={toggleColorMode}
        mr={4}
        variant="outline"
      ></IconButton>
      <Component {...pageProps} />
    </ChakraProvider>
  )
I had left the old instace there
the first time
the iconButton component?
Avatar
So, the ChakraProvider Provides the Context for useColorMode, so the useColorMode cannot be in the App.tsx, but in a seperate file.
Create a ColorModeButton.tsx or such to write as below
Avatar
Chinese perchOP
don't mind me asking,
i've been using .js files till now
what is tsx
It gives a react symbol
jsx?
Avatar
Oh
I'm used to typescript so nvm
Avatar
Chinese perchOP
oh right
typescript
Avatar
ColorModeButton.js
export default function ColorModeButton() {
  const { colorMode, toggleColorMode } = useColorMode(); // Now the useColorMode will work
  return (    
      <IconButton
        icon={colorMode === "light" ? <SunIcon /> : <MoonIcon />}
        onClick={toggleColorMode}
        mr={4}
        variant="outline"
      />
  )
}


App.js
export default function App({ Component, pageProps }) {
  return (
    <ChakraProvider>
      <ColorModeButton />
      <Component {...pageProps} />
    </ChakraProvider>
  )
}
Answer
Avatar
Chinese perchOP
do I still have to set the
useColorMode()
in _app.js?
Avatar
my bad, remove it. (I updated the Code)
Avatar
Chinese perchOP
sure
what about the import statement?
import {themeToggle} from '../components/themeToggle.js';
??
like this?
Avatar
Since the module is exported as default (check the export default) so you can import module as

import ThemeToggle from "../components/themeTogge.js"


Also, I recommend PascalCase (using captial letters for first and every space)
Avatar
Chinese perchOP
Got it. I call it CamelCase
Thanks so much, it worked
Avatar
camelCase is the one which starts with small case
Image
FYI
Avatar
Chinese perchOP
ohh
New information
Thanks again
Avatar
Chinese perchOP
Hey!
Avatar
Yup
Avatar
Chinese perchOP
I have a doubt about the positioning. what unit is used? cause it works even without units. I want to place the icon on the top right corner. so I used this:
<Box pos="absolute" top="0" left="100vw">
  <IconButton
    icon={colorMode === "light" ? <SunIcon /> : <MoonIcon />}
    onClick={toggleColorMode}
    mr={4}
    variant="outline"
  ></IconButton>
</Box>

This places it too much to the right. it goes out of the screen
Unit used in Chakra UI is 0.25rem if you don't provide the unit.
Avatar
Chinese perchOP
Why doesn't 100vw work though?
I used to use it before in some of my projects and it never worked properly
Avatar
100vw will move one screen-width right, since the vw is 1/100 of screen width
Avatar
Chinese perchOP
exactly
so
It should be properly positioned right?
oohh
I get it
nvm
It moves it 1 screen right
So the left edge is on the screen edge
Avatar
Yup. use right="0" for it (If I understanded right)
Yes!
Avatar
Chinese perchOP
I'm very sorry if I'm disturbing you
screenshot is from the top
it worked with left
-50 value works, but why not 0?
Avatar
Hmm that's strange
Avatar
Chinese perchOP
I got it
Avatar
Okay
Avatar
Chinese perchOP
Seems like there is a div there
Why though
Avatar
What div?
Avatar
Chinese perchOP
Image
Avatar
If you use pages, Next will create a div called #__next to render React Componetns
Avatar
Chinese perchOP
ic
so... src or smth?
Avatar
You can style them with external css file
but It's weird... Normally it should be not styled.
Can you show me your App.js ?
Avatar
Chinese perchOP
import '../styles/global.css';
import { ChakraProvider, IconButton, useColorMode } from '@chakra-ui/react'
import { MoonIcon, SunIcon } from "@chakra-ui/icons";
import ThemeToggle  from '../components/ThemeToggle.js';

export default function App({ Component, pageProps }) {
  return (
    <ChakraProvider>
      <ThemeToggle  />
      <Component {...pageProps} />
    </ChakraProvider>
  )
}
Avatar
Oh I see, can you provide the styles/global.css too?
Avatar
Chinese perchOP
is it this causing the issue? I didn't actually see this file. it's the default code from the next tutorial
html,
body {
  font-family: var(--font-family);
  line-height: 1.6;
  font-size: 18px;
}

* {
  box-sizing: border-box;
}

a {
  color: #0070f3;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

img {
  max-width: 100%;
  display: block;
}
its not. I though border box might have a difference
I removed everything and tried
No change
Avatar
Hmm...
Can you show me the Elements Page (not the React Component Page) of the Developer console, selecting div#__next?
Avatar
Chinese perchOP
Image
Avatar
Hmm.. that's really odd
Avatar
Chinese perchOP
Something that might narrow it down perhaps? I found that the difference in height changes depending on the page and the content it has
so it's not due to any global css
or js
Avatar
Is the global.css empty? (or removed?) If I were you, I would start checking the html and body styles first.
Avatar
Chinese perchOP
I empty'd it and checked
no change
Avatar
Might be the #__next 's css position is not relative (because it's static in default) so it can make a problem