I have a custom hook for light/dark mode using MUI, it exports a state variable which I then pass to MUI's createTheme to tell it what theme to use. However I can't access the state variable outside of my hook, getting undefined when I console.log it. Anyone know what I'm doing wrong? I took this code directly from the MUI documentation.
Hook code:
const useProvideColorTheme = () => {
const [mode, setMode] = useState<PaletteMode>('light');
const colorMode = useMemo(
() => ({
toggleColorMode: () => {
setMode((prevMode: PaletteMode) =>
prevMode === 'light' ? 'dark' : 'light',
);
},
}),
[],
);
return {
colorMode,
mode,
setMode,
};
}
in _app.tsx
import { ProvideColorTheme, useColorTheme } from '../lib/hooks/useColorTheme';
import { createTheme, ThemeProvider } from '@mui/material/styles';
const getDesignTokens = (mode) => {...}
function MyApp({ Component, pageProps }) {
const appTheme = useColorTheme();
const theme = useMemo(() => createTheme(getDesignTokens(appTheme.mode)), [appTheme.mode]);
return (
<hook>
<hook>
<hook>
<ProvideColorTheme>
<ThemeProvider theme={theme}>
<hook>
<hook>
<Component {...pageProps} />
</hook>
</hook>
</ThemeProvider>
</ProvideColorTheme>
</hook>
</hook>
</hook>
);
}
MUI Versions
"@mui/styles": "^5.8.0"
"@mui/material": "^5.6.4"
React/Next.js Versions
"react": "18.1.0"
"react-dom": "18.1.0"
"next": "12.1.6"
CodePudding user response:
You cant access it inside your file because that app doesn't exist within ProvideColorTheme
. Technically useColorTheme
before it gets rendered within the app. This is why your MyApp
component needs to live within it.
I would recommend making a CustomProviders file which wrap your app. Something like I have below will work.
const AppProviders = () => {
return (
<ProvideColorTheme>
<MyApp />
</ProvideColorTheme>
)
}
function MyApp({ Component, pageProps }) {
const appTheme = useColorTheme();
const theme = useMemo(() => createTheme(getDesignTokens(appTheme.mode)), [appTheme.mode]);
return (
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
);
}
This is the issue with providers and you will often get put into 'Provider Hell' where you have dozens of providers that all need each other.