最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using useContext and useReducer in NextJS and reading null as context - Stack Overflow

programmeradmin1浏览0评论

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:

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

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

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

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

Share Improve this question edited May 15, 2022 at 23:04 nacairns asked May 15, 2022 at 22:25 nacairnsnacairns 2321 gold badge3 silver badges8 bronze badges 3
  • 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
Add a ment  | 

1 Answer 1

Reset to default 2

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

发布评论

评论列表(0)

  1. 暂无评论