Next.js Discord

Discord Forum

Error: invalid hook call using

Answered
Chinese perch posted this in #help-forum
Open in Discord
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

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
Original message was deleted
Chinese perchOP
can you possibly explain? I'm new to next
client side rendering?
Move
const { colorMode, toggleColorMode } = useColorMode();

Into App
@Chinese perch client side rendering?
sorry nvm, this is pages router...
Chinese perchOP
uh.. ok
Since useColorMode is a hook and as App is used in there, there is no need to use "use client" here
@alfonsus sorry nvm, this is pages router...
Yup I think it is too
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();
@maxswjeon Move const { colorMode, toggleColorMode } = useColorMode(); Into `App`
Chinese perchOP
I had tried that before too. error is above
Oh I see
Chinese perchOP
oh wait
Wait
so the useColorMode should be inside the ChakraProvider
Okay
Chinese perchOP
My bad
my bad
@maxswjeon so the `useColorMode` should be inside the `ChakraProvider`
Chinese perchOP
The page now loads, but the button does not work
So how did you moved the useColorMode now?
I think the Button should be a seperate component in seperate file
@maxswjeon So how did you moved the `useColorMode` now?
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
@maxswjeon I think the Button should be a seperate component in seperate file
Chinese perchOP
the iconButton component?
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
Chinese perchOP
don't mind me asking,
i've been using .js files till now
what is tsx
It gives a react symbol
jsx?
Oh
I'm used to typescript so nvm
Chinese perchOP
oh right
typescript
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
Chinese perchOP
do I still have to set the
useColorMode()
in _app.js?
my bad, remove it. (I updated the Code)
Chinese perchOP
sure
@maxswjeon my bad, remove it. (I updated the Code)
Chinese perchOP
what about the import statement?
import {themeToggle} from '../components/themeToggle.js';
??
like this?
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)
camelCase is the one which starts with small case
FYI
Chinese perchOP
ohh
New information
Thanks again
Chinese perchOP
Hey!
Yup
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.
Chinese perchOP
Why doesn't 100vw work though?
I used to use it before in some of my projects and it never worked properly
100vw will move one screen-width right, since the vw is 1/100 of screen width
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
Yup. use right="0" for it (If I understanded right)
Yes!
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?
Hmm that's strange
Chinese perchOP
I got it
Okay
Chinese perchOP
Seems like there is a div there
Why though
What div?
Chinese perchOP
If you use pages, Next will create a div called #__next to render React Componetns
Chinese perchOP
ic
so... src or smth?
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 ?
@maxswjeon Can you show me your `App.js` ?
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>
  )
}
Oh I see, can you provide the styles/global.css too?
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
Hmm...
Can you show me the Elements Page (not the React Component Page) of the Developer console, selecting div#__next?
Chinese perchOP
Hmm.. that's really odd
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
Is the global.css empty? (or removed?) If I were you, I would start checking the html and body styles first.
Chinese perchOP
I empty'd it and checked
no change
Might be the #__next 's css position is not relative (because it's static in default) so it can make a problem