reactjs 使用材质-用户界面主题更改根背景色

vof42yt1  于 2023-02-03  发布在  React
关注(0)|答案(8)|浏览(148)

我在尝试一个很简单的方法:使用Material-UI主题为网站构建两个主题:
一个light主题和一个dark主题,但效果不佳:主题在每个Material-UI react元素上,但是html文档上的根元素保持相同的默认白色背景。
当然,它可以通过用pure .css攻击身体来改变:

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

我在这里迷路了,有没有办法使这个与材料用户界面的主题?

3duebb1j

3duebb1j1#

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

u1ehiz5o

u1ehiz5o2#

MUI v5中,还可以使用GlobalStyles组件将样式添加到body元素中:

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

idfiyjo8

idfiyjo83#

除了@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;

(我只是出于习惯使用class组件😅)
嵌套主题MUI Theme toggle的完整示例

kkih6yb8

kkih6yb84#

我的用例,我只想在React组件中更改bodybackground-color,而不是整个主题。
TL;DR代码:

// other imports ...
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles((theme) => ({
  '@global':{
      body:{
        backgroundColor:"#382E7E"
      }
  },
  otherstyles:{
    //  other styles ....
  },

}));

// React component, etc ...
4ioopgfo

4ioopgfo5#

MUI版本5

import { createTheme } from "@mui/material/styles";

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

MUI版本4

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

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

同样简单的是,改变托盘类型为暗默认设置为亮。2这也将有助于自定义颜色的其他组件,如排版,图标等

bjp0bcyl

bjp0bcyl6#

ReactDOM不会替换目标元素。我个人没有使用过材质ui。但是,如果您将所需的背景色放入App状态中,例如'currentRootColor',则可以在App组件的呈现函数中放入:

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

    ...the rest of your App render code
}

这将设置主体的背景色,如果您更改'this.state. currentRootColor',则应用组件将使用新的背景色重新呈现。
但是,如果< body >您的文档中还没有标记,则需要添加一个。

nr9pn0ug

nr9pn0ug7#

在MUI v5中,这似乎对我很有效,我用它只对主页应用特定的样式(覆盖默认样式)。

pages/HomePage.js

...

import GlobalStyles from '@mui/material/GlobalStyles';
// or
import { GlobalStyles } from '@mui/material';

注意:将<GlobalStyles />提升为静态常量是一个很好的做法,以避免重新渲染。这将确保生成的标记不会在每次渲染时重新计算。

const homePageStyles = (
    <GlobalStyles
      styles={{
        body: { backgroundColor: 'cyan' },
        '.MuiTypography-root': {
          color: 'red',
        },
      }}
    />
  );

...

return (
    <>
      {homePageStyles}
      <MyComponents />
    </>
);

....
更多信息:
https://mui.com/material-ui/customization/how-to-customize/
https://mui.com/material-ui/api/global-styles/

cngwdvgl

cngwdvgl8#

以上所有的答案对我都不起作用,为什么??我不知道。
我用ScopedCssBaseline覆盖了我的所有组件,mui将只对子组件应用调色板样式。
以下是我的回答,

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

const themeLight = createTheme({
  palette: {
    background: {
      default: "#fff"
    },
    text: {
      default: "#000"
    }
  }
});

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

const App = () => {
  const [light, setLight] = React.useState(true);

  return (
    <ThemeProvider theme={light ? themeLight : themeDark}>
      <ScopedCssBaseline enableColorScheme>
        <Button onClick={() => setLight((prev) => !prev)}>Toggle Theme</Button>
      </ScopedCssBaseline>
    </ThemeProvider>
  );
};

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

相关问题