skip to Main Content

So I have a problem with useContext in React. I want to update it in my parent component, then use it in child components. However, while the context seem to work properly inside my parent component, when I want to use it in the children, it’s undefined (still has its default value).

The code snippets that illustrate the problem:

LobbyContext.tsx

import React, {createContext, useState} from "react";
import { ILobby } from "@/components/GameIndex";

interface ILobbyContext {
    lobby: ILobby | undefined;
    setLobby: React.Dispatch<React.SetStateAction<ILobby | undefined>>;
}

export const LobbyContext = createContext<ILobbyContext>({
    lobby: "",
    setLobby: () => {
        console.log("old function")}
});

export function LobbyProvider({ children }: { children: React.ReactNode }) {
    const [lobby, setLobby] = useState<ILobby | undefined>();

    return (
        <LobbyContext.Provider value={{ lobby, setLobby }}>
            {children}
        </LobbyContext.Provider>
    );
}

/game/[id].tsx

import {LobbyProvider} from "@/context/LobbyContext";
import GameIndex from "@/components/GameIndex"
const Index = () => {

    return (
            <LobbyProvider>
                <GameIndex />
            </LobbyProvider>
    );
};

export default Index;

fragments of GameIndex.tsx

const { lobby, setLobby } = useContext(LobbyContext);

/*...*/

useEffect(() => {
            fetch(`http://localhost:8080/api/lobby/${lobbyId}`)
        .then(data => {
            setLobby(data);
        }
, [lobby, setLobby] }

/*...*/

    return (
       {lobby !== undefined ? <Scoreboard/> : <div>Loading...</div>}
    );

Scoreboard.tsx

import {LobbyContext} from "@/context/LobbyContext";

const Scoreboard = () => {
    const {lobby, setLobby} = useContext(LobbyContext);

return (
        <div className={"scoreboard flex-col"}>
        {lobby}
        </div>
    );
}

ironically, Scoreboard renders, because lobby is defined inside of GameIndex.tsx, but inside of Scoreboard, it’s undefined…

What am I doing wrong?

2

Answers


  1. Chosen as BEST ANSWER

    I solved this issue - it turns I have used ContextProvider twice - both in /game/[id].tsx and GameIndex.tsx. By removing the GameIndex provider, the context now works as intended.


  2. When processing the fetch request, you should parse the retrieved data as JSON and pass this processed data to the setLobby function.
    Update the default value type in the LobbyContext to ILobby.
    Within the useEffect hook, specify the dependencies of the fetch request. In this case, include the lobbyId dependency.
    By making these adjustments, the lobby variable in the Scoreboard component should no longer be undefined and should receive the correct value.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search