首页 > 解决方案 > 如何将我的明暗模式主题包裹在 index.js 周围,同时使用我的标题作为切换位置?

问题描述

我对如何设置围绕我的 index.js 组件的主题有点困惑,同时在我的 header.js 中使用触发lightdark主题的开关状态。

试图尽可能简化这一点,以减少编码。但是,我是 React Noob,希望获得一些有关如何正确设置代码以使一切正常运行的指导。

编辑:感谢 Diyorbek,我已经设法了解如何使其正常工作。我现在得到一个theme未为我的index.js文件定义

import { ThemeProvider, CssBaseline } from "@material-ui/core";
import { createMuiTheme } from "@material-ui/core";

const MyThemeContext = React.createContext({});

export function useMyThemeContext() {
  return useContext(MyThemeContext);
}

function MyThemeProvider(props) {
  const [isDarkMode, setIsDarkMode] = useState(false);

  const theme = useMemo(
    () =>
      createMuiTheme({
        palette: {
          type: isDarkMode ? 'dark' : 'light',
        },
      }),
    [isDarkMode]
  );

  return (
    <ThemeProvider theme={theme}>
      <MyThemeContext.Provider value={{ isDarkMode, setIsDarkMode }}>
        {props.children}
      </MyThemeContext.Provider>
    </ThemeProvider>
  );
}


const routing = (
    <Router>
        <React.StrictMode>
            <ThemeProvider theme={theme}>
                <CssBaseline />
                    <Header />
                    <Switch>
                        <Route exact path="/" component={App} />
                    </Switch>
                    <Footer />
            </ThemeProvider>
        </React.StrictMode>
    </Router>
);

ReactDOM.render(routing, document.getElementById('root'));

header.js

import { useMyThemeContext } from '../index';


const useStyles = makeStyles((theme) => ({
    appBar: {
        borderBottom: `1px solid ${theme.palette.divider}`,
    },
    link: {
        margin: theme.spacing(1, 1.5),
    },
    toolbarTitle: {
        flexGrow: 1,
    },
}));


function Header() {
    const classes = useStyles();

    const [isDarkMode, setIsDarkMode] = useMyThemeContext();

    return (
        <React.Fragment>
            <CssBaseline />
            <AppBar
                position="static"
                color="default"
                elevation={0}
                className={classes.appBar}
            >
                <Toolbar className={classes.toolbar}>
                    <Switch
                        checked={isDarkMode}
                        onChange={() => setIsDarkMode(!isDarkMode)}
                    />
                </Toolbar>
            </AppBar>
        </React.Fragment>
    );
}

export default Header;

提前感谢您的帮助:)

标签: javascriptreactjsmaterial-ui

解决方案


你应该使用React Context。这就是我处理这种情况的方式:

const MyThemeContext = createContext({});

export function useMyThemeContext() {
  return useContext(MyThemeContext);
}

function MyThemeProvider(props) {
  const [isDarkMode, setIsDarkMode] = useState(false);

  const theme = useMemo(
    () =>
      createMuiTheme({
        palette: {
          type: isDarkMode ? 'dark' : 'light',
        },
      }),
    [isDarkMode]
  );

  return (
    <ThemeProvider theme={theme}>
      <MyThemeContext.Provider value={{ isDarkMode, setIsDarkMode }}>
        {props.children}
      </MyThemeContext.Provider>
    </ThemeProvider>
  );
}

const routing = (
  <Router>
    <React.StrictMode>
      <MyThemeProvider>
        <CssBaseline />
        <Header />
        <Switch>
          <Route exact path="/" component={App} />
        </Switch>
        <Footer />
      </MyThemeProvider>
    </React.StrictMode>
  </Router>
);
import { useMyThemeContext } from "...."

function Header() {
  const classes = useStyles();

  const {isDarkMode, setIsDarkMode} = useMyThemeContext();

  return (
    <React.Fragment>
      <CssBaseline />
      <AppBar
        position="static"
        color="default"
        elevation={0}
        className={classes.appBar}
      >
        <Toolbar className={classes.toolbar}>
          <Switch
            checked={isDarkMode}
            onChange={() => setIsDarkMode(!isDarkMode)}
          />
        </Toolbar>
      </AppBar>
    </React.Fragment>
  );
}

推荐阅读