I’m stuck creating a dark mode toggle feature for my web app. I’m using NextJS with Material UI.
I’ve tried to create a React context which contains a useState
and have a switch component change the context.
theme.tsx
This is where I define my theme which is fed into the _app.js
file.
// const { darkMode }: ColorModeContextType = useColorModeContext()
// This line doesn't work since technically `theme.tsx` is outside of the React context I defined.
const muiTheme: Theme = createTheme()
export const baseTheme: Theme = createTheme({
palette: { mode: darkMode ? "dark" : "light" },
...
colorMode.tsx
I define my React context which is used in the _app.js
file as <ColorModeContext.Provider>...</ColorModeContext.Provider>
...
const ColorModeContext: Context<ColorModeContextType> = createContext({
darkMode: false,
setDarkMode: (darkMode: boolean) => {},
})
export const useColorModeContext = () => {
return useContext(ColorModeContext)
}
interface ColorModeContextProps {
children: ReactNode
}
export function ColorModeProvider({ children }: ColorModeContextProps) {
const [darkMode, setDarkMode] = useState<boolean>(false)
const colorModeContext = useMemo(
() => ({ darkMode, setDarkMode }),
[darkMode]
)
return (
<ColorModeContext.Provider value={colorModeContext}>
{children}
</ColorModeContext.Provider>
)
}
appbar.tsx
Where the user can switch dark mode on or off.
...
const { darkMode, setDarkMode }: ColorModeContextType = useColorModeContext()
const handleDarkModeSelect = (
_event: ChangeEvent<HTMLInputElement>,
value: boolean
) => {
setDarkMode(value)
}
return (
<CustomDarkModeSwitch
defaultChecked={false}
onChange={(event: ChangeEvent<HTMLInputElement>, value: boolean) =>
handleDarkModeSelect(event, value)
}
)
/>
I’ve tried to fit the example at https://mui.com/material-ui/customization/dark-mode to my use case but I’m struggling.
My problem in my case is the theme.jsx
file does not recognize the context so I can’t have the context alter the theme. This is the error:
Server Error
TypeError: Cannot read properties of null (reading 'useContext')
2
Answers
Instead of trying to the ColorModeContext inside the ThemeProvider, I put the ThemeProvider around the ColorModeContext.
you’re trying to use the useContext hook outside of a component. It’s possible that you’re importing the theme.tsx file directly in the top-level scope of your application, which would cause the error since useContext can only be used within a component. Try this: