在暗/亮模式材质 UI 之间切换

时间:2021-07-14 17:28:22

标签: reactjs material-ui

我就是想不通。我想用 Switch 改变背景,但它只在第一次工作,在随后的点击中不起作用。 这是代码沙箱:

https://codesandbox.io/s/strange-shaw-2tfk5

谁能告诉我这是怎么回事?我在 React 中使用 Material UI

最小可重现示例: 这是我的应用组件

import React from "react";
import { useState } from "react";
import { ThemeProvider, createTheme } from "@material-ui/core/styles";
import { Container, Switch, CssBaseline } from "@material-ui/core";

const darkTheme = createTheme({
  palette: {
    type: "dark",
    background: {
      default: "hsl(230, 17%, 14%)"
    }
  }
});

const lightTheme = createTheme({
  palette: {
    type: "light",
    background: {
      default: "hsl(0, 0%, 100%)"
    }
  }
});

const App = () => {
  const [mode, setMode] = useState("light");

  const selectedTheme = mode === "dark" ? darkTheme : lightTheme;

  return (
    <ThemeProvider theme={selectedTheme}>
      <CssBaseline />
      <Container maxWidth="lg">
        <h1>Hello</h1>
        <Switch onChange={() => setMode(mode === "light" ? "dark" : "light")} />
      </Container>
    </ThemeProvider>
  );
};

export default App;

3 个答案:

答案 0 :(得分:3)

根据Material UI documentation,要在明暗之间切换,他们建议useMemo按需创建新主题:

import { useState, useMemo } from "react";

function App() {
  const [mode, setMode] = useState("light");

  const theme = useMemo(
    () =>
      createTheme({
        palette: {
          type: mode,
          background: {
            dark: "hsl(230, 17%, 14%)",
            light: "hsl(0, 0%, 100%)"
          }
        }
      }),
    [mode]
  );

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <Container maxWidth="lg">
        <h1>Hello</h1>
        <Switch onChange={() => setMode(mode === "light" ? "dark" : "light")} />
      </Container>
    </ThemeProvider>
  );
}

即使使用 StrictMode 这也能工作。

在组件外部定义时它不适用于 StrictMode 的原因在 a Github issue 中得到解决,其中指出此行为应在 v5(仍处于测试阶段)中修复。

答案 1 :(得分:1)

不知道为什么,但在 index.js 中删除 StrictMode 解决了问题

答案 2 :(得分:0)

您可以将主题变量放在应用程序组件中: https://codesandbox.io/s/tender-lederberg-8v7tx?file=/src/App.js 或动态更改主题属性: https://codesandbox.io/s/magical-ives-587fm?file=/src/App.js