想要在Material UI主题中动态更改(拾取)原色

Nit*_*nde 3 themes reactjs material-ui

有一个要求,我想授予用户访问权,可以从诸如蓝色,橙色绿色的列表中选择其原色。我已将最新的Material UI用于前端。

现在我可以将浅色主题更改为深色主题,但我的要求也就是更改原色。请帮助我同样如何编码相同。

请检查附件屏幕:

在此处输入图片说明

Ade*_*ran 7

import React from 'react';
import { render } from 'react-dom';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import Root from './Root';

import lightTheme from 'your-light-theme-path';
import darkTheme from 'your-dark-them-path';

const theme1 = createMuiTheme(lightTheme);
const theme2 = createMuiTheme(darkTheme)

class App extends React.Component {
  state = {
    isThemeLight: true;
  }
  onChange = () => {
    this.setState=({ isThemeLight: false })
  }
  render() {
     const { isThemeLight } = this.state;
     return (
       <MuiThemeProvider theme={isThemeLight ? theme1 : theme2}>
         <Root /> // your app here
         <button onClick={this.onChange}>Change Dark</button>
       </MuiThemeProvider>
     );
  }
}

render(<App />, document.querySelector('#app'));
Run Code Online (Sandbox Code Playgroud)

您的lightThemedarkTheme可以是这样的文件

export default {
  direction: 'ltr',
  palette: {
    type: 'light',
     primary: {
       main: '#37b44e',
     },
     secondary: {
       main: '#000',
     },
  },
};
Run Code Online (Sandbox Code Playgroud)

您可以在Material UI Docs Theme Configuration中查看所有可配置的主题列表

方法2(用于主题更改运行时)

import React from 'react';
import { render } from 'react-dom';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import Root from './Root';

const theme1 = createMuiTheme(lightTheme);
const theme2 = createMuiTheme(darkTheme)

class App extends React.Component {
  state = {
    theme1: {
       palette: {
         type: 'light',
         primary: { main: '#37b44e' },
         secondary: { main: '#000' },
       },
    };
    theme2: {
       palette: {
         type: 'light',
         primary: { main: '#37b44e' },
         secondary: { main: '#000' },
       },
    };
    isThemeLight: true;
  }
  onChange = () => {
    this.setState=({ isThemeLight: false })
  }
  onChangeTheme1 = () => {
    this.setState(({theme1}) => ({
       theme1: { 
        ...theme1,
        primary: { main: 'red' },
       }
    }));
  }
  render() {
     const { theme1, theme2, isThemeLight } = this.state;
     return (
       <MuiThemeProvider 
         theme={isThemeLight ? createMuiTheme(theme1) : createMuiTheme(theme2)}
       >
         <Root /> // your app here
         <button onClick={this.onChange}>Change Dark</button>
         <button onClick={this.onChangeTheme1}>Change Palette Theme 1</button>
       </MuiThemeProvider>
     );
  }
}

render(<App />, document.querySelector('#app'));
Run Code Online (Sandbox Code Playgroud)

  • 在运行时更改 mui 主题效果很好,但我注意到每次调用函数 `createMuiTheme` 时,都会在运行时添加一堆 css 样式文件,因此更改主题 10 次将创建 10 个(或可能更多)相同的主题文件! (3认同)

Nea*_*arl 5

每当状态发生变化时,您都可以用来useMemo计算主题对象primaryColorsetPrimaryColor()用户在 UI 中选择一个选项后,可以更新状态:

const [primaryColor, setPrimaryColor] = React.useState(defaultColor);
const theme = React.useMemo(
  () =>
    createTheme({
      palette: {
        primary: {
          main: primaryColor,
        },
      },
    }),
  [primaryColor],
);
Run Code Online (Sandbox Code Playgroud)

这是一个最小的工作示例:

const defaultColor = '#f44336';
const [primaryColor, setPrimaryColor] = React.useState(defaultColor);
const theme = React.useMemo(
  () =>
    createTheme({
      palette: {
        primary: { main: primaryColor },
      },
    }),
  [primaryColor],
);

return (
  <ThemeProvider theme={theme}>
    <Box m={2}>
      <TextField
        select
        sx={{ width: 100 }}
        label="Primary color"
        defaultValue={defaultColor}
        onChange={(e) => setPrimaryColor(e.target.value)}
      >
        <MenuItem value="#f44336">Red</MenuItem>
        <MenuItem value="#2196f3">Blue</MenuItem>
        <MenuItem value="#4caf50">Green</MenuItem>
      </TextField>
      <Checkbox defaultChecked />
    </Box>
  </ThemeProvider>
);
Run Code Online (Sandbox Code Playgroud)

现场演示

Codesandbox 演示