Attempting to create a tic-tac-toe game in NextJS and trying to create a board context for my ponents to read. Once I introduced a reducer into the Wrapper for a more plex state, I am now getting a null error.
Errors:
TypeError: Cannot read properties of null (reading 'useContext')
Error in then the terminal:
Warning: Invalid hook call. Hooks can only be called inside of the body of a function ponent. 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
I believe I only have the react version installed in this project that next installs when using create-next-app. I'm largely stuck on where to look for what's going wrong. Can I not use the useReducer hook instead of the useState hook when providing context in NextJS?
Context Declaration:
const TTTContext = createContext();
const TTTBoard = new Board(3);
const gameStateReducer = (state, action) => {
switch (action.type) {
//...reducer logic
}
}
const TTTWrapper = ({ children }) => {
const [gameState, dispatch] = useReducer(gameStateReducer, {board: TTTBoard, playerPiece:"DEFAULT"});
const gameContextValue = () => {gameState, dispatch};
return (
<TTTContext.Provider value={gameContextValue}>
{children}
</TTTContext.Provider>
);
}
const useTTTContext = () => {
return useContext(TTTContext)
};
module.exports = { TTTWrapper, useTTTContext }
The context is applied in _app.js here:
<TTTWrapper>
<Component {...pageProps} />
</TTTWrapper>
And the game state is retrieved in the actual Grid ponent here:
import { useTTTContext } from "../contexts/TTTContext";
const {gameState, dispatch} = useTTTContext();
Solved: const {gameState, dispatch} = useTTTContext();
was outside of its ponent body.
Attempting to create a tic-tac-toe game in NextJS and trying to create a board context for my ponents to read. Once I introduced a reducer into the Wrapper for a more plex state, I am now getting a null error.
Errors:
TypeError: Cannot read properties of null (reading 'useContext')
Error in then the terminal:
Warning: Invalid hook call. Hooks can only be called inside of the body of a function ponent. 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
I believe I only have the react version installed in this project that next installs when using create-next-app. I'm largely stuck on where to look for what's going wrong. Can I not use the useReducer hook instead of the useState hook when providing context in NextJS?
Context Declaration:
const TTTContext = createContext();
const TTTBoard = new Board(3);
const gameStateReducer = (state, action) => {
switch (action.type) {
//...reducer logic
}
}
const TTTWrapper = ({ children }) => {
const [gameState, dispatch] = useReducer(gameStateReducer, {board: TTTBoard, playerPiece:"DEFAULT"});
const gameContextValue = () => {gameState, dispatch};
return (
<TTTContext.Provider value={gameContextValue}>
{children}
</TTTContext.Provider>
);
}
const useTTTContext = () => {
return useContext(TTTContext)
};
module.exports = { TTTWrapper, useTTTContext }
The context is applied in _app.js here:
<TTTWrapper>
<Component {...pageProps} />
</TTTWrapper>
And the game state is retrieved in the actual Grid ponent here:
import { useTTTContext } from "../contexts/TTTContext";
const {gameState, dispatch} = useTTTContext();
Solved: const {gameState, dispatch} = useTTTContext();
was outside of its ponent body.
-
Shouldn't you also simply be passing
{gameState, dispatch}
to the context, i.e.<TTTContext.Provider value={{gameState, dispatch}}>
? – juliomalves Commented May 15, 2022 at 22:50 -
1
What is the
const {gameState, dispatch} = useTTTContext();
of the last snippet? Where exactly is that code located/called? If it's not inside a React ponent body or another custom React hook that this seems to be the culprit. – Drew Reese Commented May 15, 2022 at 23:01 - @DrewReese Yep, that was the culprit. Thanks for the help. It was outside of the Grid ponent body. – nacairns Commented May 15, 2022 at 23:03
1 Answer
Reset to default 2From what I can see of the code you've provided, the issue seems to be in the last snippet:
import { useTTTContext } from "../contexts/TTTContext";
const {gameState, dispatch} = useTTTContext();
The useTTTContext
doesn't appear to be used/called inside any React function ponent body nor any custom React hook. It should be moved into either a React function or custom hook body.