Home > Enterprise >  Using useContext and useReducer in NextJS and reading null as context
Using useContext and useReducer in NextJS and reading null as context

Time:05-16

Attempting to create a tic-tac-toe game in NextJS and trying to create a board context for my components to read. Once I introduced a reducer into the Wrapper for a more complex 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 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

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 component here:

import { useTTTContext } from "../contexts/TTTContext";
const {gameState, dispatch} = useTTTContext();

Solved: const {gameState, dispatch} = useTTTContext(); was outside of its component body.

CodePudding user response:

From 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 component body nor any custom React hook. It should be moved into either a React function or custom hook body.

  • Related