使用 Material-UI 主题更改根背景颜色

IT技术 reactjs material-ui
2021-04-11 13:17:59

我正在尝试一些非常简单的事情:使用 Material-UI 主题为网站构建两个主题:

一个light主题和dark一个,但效果不佳:主题位于每个 Material-UI react 元素上,但 html 文档上的根元素保持相同的默认白色背景。

当然可以通过纯.css攻击body来改变:

body {
  background-color: #222;
}

但我想用 React 动态改变它,我虽然这会起作用,但它不会:

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

const themeLight = createMuiTheme({
  palette: {
    background: {
      default: "#e4f0e2"
    }
  },
});

const themeDark = createMuiTheme({
  palette: {
    background: {
      default: "#222222",
    }
  },
});

ReactDOM.render(
  <MuiThemeProvider theme = { themeDark }>
    <App />
  </MuiThemeProvider>, document.getElementById('root'));

我在这里迷路了,没有办法用 Material-UI 主题做这个吗?

6个回答

CssBaseline是控制这方面的组件。如果您没有使用CssBaseline,那么您只会看到浏览器提供的默认值。

这是一个有效的 v4 示例(进一步向下 v5 示例):

import React from "react";
import ReactDOM from "react-dom";
import CssBaseline from "@material-ui/core/CssBaseline";
import { MuiThemeProvider, createMuiTheme } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";

const themeLight = createMuiTheme({
  palette: {
    background: {
      default: "#e4f0e2"
    }
  }
});

const themeDark = createMuiTheme({
  palette: {
    background: {
      default: "#222222"
    },
    text: {
      primary: "#ffffff"
    }
  }
});

const App = () => {
  const [light, setLight] = React.useState(true);
  return (
    <MuiThemeProvider theme={light ? themeLight : themeDark}>
      <CssBaseline />
      <Button onClick={() => setLight(prev => !prev)}>Toggle Theme</Button>
    </MuiThemeProvider>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

编辑主题正文背景


下面是 Material-UI v5 示例。与 v4 的唯一区别是名称更改ThemeProvider(尽管此名称在 v4 中也可用MuiThemeProvider)和createTheme(代替createMuiTheme)并使用新的@mui/material包名称代替@material-ui/core

import React from "react";
import ReactDOM from "react-dom";
import CssBaseline from "@mui/material/CssBaseline";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import Button from "@mui/material/Button";

const themeLight = createTheme({
  palette: {
    background: {
      default: "#e4f0e2"
    }
  }
});

const themeDark = createTheme({
  palette: {
    background: {
      default: "#222222"
    },
    text: {
      primary: "#ffffff"
    }
  }
});

const App = () => {
  const [light, setLight] = React.useState(true);
  return (
    <ThemeProvider theme={light ? themeLight : themeDark}>
      <CssBaseline />
      <Button onClick={() => setLight((prev) => !prev)}>Toggle Theme</Button>
    </ThemeProvider>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

编辑主题正文背景

上面的信息很好!我还想补充一点,我遇到了这个问题。我需要在我的应用程序的根组件中的 <ThemeProvider> 之后添加 <StyledEngineProvider injectFirst>
2021-05-30 13:17:59
我的问题是ThemeProviderCssBaseline组件的顺序谢谢你的例子!
2021-05-31 13:17:59

在@NearHuscarl 的回答之上,在 CSSBaseLine 之后导入 GlobalStyles,将保留页面默认值(如边距:0 等),仍然能够自定义根级/全局样式。例如,

import { Component } from "react";
import { Button, CssBaseline, GlobalStyles } from "@mui/material";
import { ThemeProvider, createTheme } from "@mui/material/styles";

export class App extends Component {
  render() {
    const theme = createTheme({
      palette: {
        mode: "dark",
        primary: {
          main: "#ff0000",
          contrastText: "#fff",
        },
        secondary: {
          main: green[500],
        },
      },
    });
    return (
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <GlobalStyles
          styles={{
            body: { backgroundColor: "cyan" },
          }}
        />
        <Button color="primary" variant="contained">
          Button
        </Button>
      </ThemeProvider>
    );
  }
}

export default App;

(我只是出于习惯使用类组件😅)

带有嵌套主题的完整示例MUI 主题切换

MUI v5 中,您还可以使用GlobalStyles组件为body元素添加样式

<GlobalStyles
  styles={{
    body: { backgroundColor: "lightyellow" }
  }}
/>

编辑 59145165/change-root-background-color-with-material-ui-theme

ReactDOM 不会替换目标元素。我个人没有使用过材料 ui。但是,如果您将所需的背景颜色作为“currentRootColor”之类的内容放入 App 状态,那么您可以在 App 组件的渲染函数中放入:

render() {
    document.body.style.backgroundColor = this.state.currentRootColor;

    ...the rest of your App render code
}

这将设置主体的背景颜色,如果您更改“this.state.currentRootColor”,那么您的 App 组件将使用新的背景颜色重新呈现。

但是,如果您的文档中还没有 <body> 标签,则需要添加一个。

import { createMuiTheme } from '@material-ui/core/styles';

const themeX = createMuiTheme({
   palette: {
     type: "dark",
   }
 });

就这么简单,默认情况下将托盘类型更改为深色,将其设置为浅色。这也将有助于其他组件的自定义颜色,如排版、图标等