在运行时更改 Material UI 反应主题的最佳方式

The optimum way of changing Material UI react theme at runtime

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

Theme.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
});

App.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 挂钩,但它只能让您创建 class 可在您的组件中使用的名称。我想要的是:将现有主题对象的某个部分替换为其中的一个属性。 任何帮助将不胜感激。感谢您阅读到这里! [1]: https://material-ui.com/styles/advanced/#main-content

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

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

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

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

take a certain section of the existing theme object and replace a property in it

尝试工厂方法:

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());