首页 > 解决方案 > 在运行时更改 Material UI 反应主题的最佳方式

问题描述

我是 React 和 Material UI 的新手,但我仍在尝试掌握组合而不是继承。我正在尝试在反应应用程序中实现在运行时切换到暗/亮主题。我以某种方式实现了它,但有很多代码重复。我确信有更好的方法。这是我到目前为止所拥有的:

主题.js

import { createMuiTheme } from "@material-ui/core/styles";
    
export const darkTheme = createMuiTheme({
  palette: {
    type: "dark",
  },
 //.....a lot of items
});

export const lightTheme = createMuiTheme({
  palette: {
    type: "light",
  },

 //.....duplicating same items as above
});

应用程序.js

import { lightTheme, darkTheme } from "../shared/Theme";

const App = ({
  theme
}) => {

 return (
    <ThemeProvider theme={theme === "dark" ? darkTheme : lightTheme}>
      {/*Components...*/}
    </ThemeProvider>
  );
};

主题道具正在使用 redux 进行注入,并且工作正常。这是可行的解决方案,但不是最好的解决方案。我在 Material UI 文档中发现我们可以拥有 [外部和内部主题提供程序][1],并且我尝试执行以下操作(但它不起作用):

<ThemeProvider theme={…} >
  
  <ThemeProvider theme={outerTheme => ({ darkMode: true, ...outerTheme })}>
   {...Component}
  </ThemeProvider>
</ThemeProvider>

我知道 useStyle 钩子,但它只允许您创建可以在组件中使用的类名。我想要的是:获取现有主题对象的某个部分并替换其中的一个属性。任何帮助将不胜感激。感谢您阅读到这里![1]:https ://material-ui.com/styles/advanced/#main-content

标签: reactjsmaterial-uireact-material

解决方案


当存在属性值重复时,“重复”是一个问题,否则是一种替代配置,即重复对象或其属性不是问题。如果没有属性值重复,则使用单独的对象是一种方式,MUI 会这样做,所以你是正确的。

现在,假设您的意思是属性值重复(共享样式):

//.....duplicating same items as above

根据您的目标,在您的对象中混合使用替代配置的属性值重复:

获取现有主题对象的某个部分并替换其中的属性

尝试工厂方法:

const createThemeOptions = (isDarkMode)=>({
   palette: {
    mode: isDarkMode? "dark" : "light", // alternate configuration
   },
   primary: {
      main: indigo['A700'], // property-value repetition(shared styling)
   },
   secondary: {
      main: isDarkMode? deepOrange['A200'] : deepOrange['900'], // alternate configuration
   },
  // make your other object properties shared or alternate...
});
export const darkTheme = createMuiTheme(createThemeOptions(true));
export const lightTheme = createMuiTheme(createThemeOptions());



推荐阅读