Search code examples
reactjsreact-hooksreact-context

Context is reinitialized every time I change page


I have defined my context to store the page theme mode ("light" or "dark") as follows:

import {createContext, useState} from "react";

const SessionContext = createContext({
    mode: [],
    changeMode: () => {
    },
});

export function SessionContextProvider(props) {
    const [sessionMode, setSessionMode] = useState("dark");

    function ChangeModeHandler() {
        setSessionMode(sessionMode === "light" ? "dark" : "light")
    }

    const context = {
        mode: sessionMode,
        changeMode: ChangeModeHandler,
    };

    return (
        <SessionContext.Provider value={context}>
            {props.children}
        </SessionContext.Provider>
    );
}

export default SessionContext;

It is correctly stored and logged. Nevertheless, when I change the page, it gets always redefined as "dark", the value defined by default.

I am simply importing it at the beginning of every page as follows:

const sessionCtx = useContext(SessionContext);
console.log("Session mode: " + sessionCtx.mode)
const mode = sessionCtx.mode;

How can we avoid this situation and ensure that "light" will be respected across pages?

Edit: I am wrapping the app as follows in index.js:

import {SessionContextProvider} from "./store/session-context";

        <SessionContextProvider>
            <CssBaseline>
                <BrowserRouter>
                    <App/>
                </BrowserRouter>
            </CssBaseline>
        </SessionContextProvider>

Solution

  • I found the issue. It was not related at all with the context or how it is configured but to the Links.

    I moved from this setup (using MUI Link):

    import {Link} from "@mui/material";
    
        <ListItemButton
            component={Link}
            href="/historic"
            sx={{textDecoration: "none"}}
        >
            <ListItemIcon>
                <DashboardIcon/>
            </ListItemIcon>
            <ListItemText
                primary="Histórico"
                primaryTypographyProps={{fontSize: fontSizeMenu}}
            />
        </ListItemButton>
    

    To this other one (using "react-router-dom" Link):

    import {Link} from "react-router-dom"
    
    <Link
        to="/historic"
        style={{
            textDecoration: "none",
            color: "inherit"
        }}
    >
        <ListItemButton>
            <ListItemIcon>
                <DashboardIcon/>
            </ListItemIcon>
            <ListItemText
                primary="Histórico"
                primaryTypographyProps={{fontSize: fontSizeMenu}}
            />
        </ListItemButton>
    </Link>    
    

    While the first one shows the context reinitializing behaviour explained, the second one respects the context values stored (and it moves among endpoints faster).

    I would appreciate an explanation of why it is this way as a note to this answer, but I guess that the context is somehow only considered by library "react-router-dom".