У вас возникли проблемы из-за того, что вы пытались использовать пустой объект или полностью сгенерированный объект темы из material-ui.
Простое решение вашей проблемы - передать текущую тему через контекст и создать новая тема на его основе. Это позволит material-ui генерировать все остальные значения темы на основе типа dark / light.
function ThemeCustomProvider({ children }) {
const [theme, setTheme] = React.useState(defaultTheme());
return (
<ThemeProvider theme={createMuiTheme(theme)}>
<ThemeSetContext.Provider value={{ theme, setTheme }}>
<CssBaseline />
{children}
</ThemeSetContext.Provider>
</ThemeProvider>
);
}
В вашем компоненте мы будем использовать lodash/merge
, чтобы объединить старую тему с новыми значениями
const { theme, setTheme } = useThemeSetContext(); // The function taht will update the theme
const handleChangeDark = () => {
const newTheme = merge(
{}, // Use a new object. We don't mutate data in React
theme, // Copy the old theme values
{
palette: {
type: theme.palette.type === "light" ? "dark" : "light"
}
}
);
setTheme(newTheme); // Update the theme with the new theme that only has change dark type
setMessage(
"The theme change between dark and light, but overrides the primary color, so the primary color are always blue."
);
};
const handleChangeColor = () => {
const newTheme = merge(
{},
theme,
{
palette: {
primary: {
main: getRandomColor() // The new value
}
}
}
);
setTheme(newTheme); // Update the theme with the new object that keeps the previous values like palette type
setMessage(
"The theme change the primary color, keeping the theme dark/light theme."
);
};
Вот ваш ящик с кодами, обновленный следующими изменениями:
https://codesandbox.io/s/so-material-ui-changetheme-type-qdbe9