Материал интерфейса: темная тема не применяется - PullRequest
0 голосов
/ 06 марта 2020

Я использую Context API для хранения значения темы. Сама тема создается с помощью <createMuiTheme> и передается от <Layout> детям через <MuiThemeProvider> и <CssBaseline>. Я могу увидеть изменение состояния через React DevTools, но сама тема не применяется - и я не понимаю, почему ...

Вот codesandbox с полным примером - предупреждение : содержит Сэмюэль Л. Ипсум . Ниже приведена сокращенная версия.

Определения тем и тем по умолчанию:

// theme/dark.js
import { createMuiTheme } from "@material-ui/core/styles";

const theme = createMuiTheme({
  typography: {
    useNextVariants: true
  },
  palette: {
    type: "dark"
  }
});

export default theme;

// theme/default.js
import { createMuiTheme } from "@material-ui/core/styles";

const theme = createMuiTheme({
  typography: {
    useNextVariants: true
  },
  palette: {
    type: "light"
  }
});

export default theme;

Контекст:

// context/settings/SettingsContext.js
import React from "react";

export default React.createContext({
  darkMode: false
});

// context/settings/SettingsProvider.js
import React, { useState } from "react";
import SettingsContext from "./SettingsContext";

const storage = {
  getItem(key) {
    if (localStorage) {
      return localStorage.getItem(key);
    }
  },
  setItem(key, value) {
    if (localStorage) {
      return localStorage.setItem(key, value);
    }
  }
};

const SettingsProvider = props => {
  const [darkMode, setDarkMode] = useState(
    storage.getItem("darkMode") === "true"
  );
  const onSetDarkMode = darkMode => {
    setDarkMode(darkMode);
    storage.setItem("darkMode", darkMode);
  };
  return (
    <SettingsContext.Provider
      value={{
        darkMode,
        onSetDarkMode
      }}
    >
      {props.children}
    </SettingsContext.Provider>
  );
};

export default SettingsProvider;

index.js:

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./containers/app";
import SettingsProvider from "./context/settings/SettingsProvider";

ReactDOM.render(
  <BrowserRouter>
    <SettingsProvider>
      <App />
    </SettingsProvider>
  </BrowserRouter>,
  document.getElementById("root")

app/index.js:

import React, { useState } from "react";
import { Switch, Route } from "react-router-dom";
import { default as home } from "../home/routes";
import Layout from "../layout";

const App = () => {
  const [anchorEl, setAnchorEl] = useState(null);
  return (
    <div>
      <Layout anchorEl={anchorEl} setAnchorEl={setAnchorEl}>
        <Switch>
          {home.map((route, index) => (
            <Route
              key={index}
              path={route.path}
              exact={route.exact}
              render={route.render}
            />
          ))}
        </Switch>
      </Layout>
    </div>
  );
};

export default App;

И layout/index.js:

import React, { useContext } from "react";
import { MuiThemeProvider } from "@material-ui/core/styles";
import { makeStyles } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import defaultTheme from "../../themes/default";
import darkTheme from "../../themes/default";
import SettingsContext from "../../context/settings/SettingsContext";
import Header from "../../components/header/index";

const useStyles = makeStyles(theme => ({
  toolbarMargin: {
    ...theme.mixins.toolbar
  }
}));

const Layout = props => {
  const classes = useStyles();
  const context = useContext(SettingsContext);
  const theme = context.darkMode ? darkTheme : defaultTheme;
  const { children, anchorEl, setAnchorEl } = props;

  return (
    <MuiThemeProvider theme={theme}>
      <CssBaseline />
      <Header anchorEl={anchorEl} setAnchorEl={setAnchorEl} />
      <main>
        <div className={classes.toolbarMargin} />
        {children}
      </main>
    </MuiThemeProvider>
  );
};

export default Layout;

Что я пропустил?

1 Ответ

2 голосов
/ 06 марта 2020

Вы импортируете одну и ту же тему дважды. Я бы предложил использовать именованные экспорты вместо значений по умолчанию, это очень помогает при автоматическом импорте, а также выявляет ошибки, подобные этой.

// layout/index.js

import defaultTheme from "../../themes/default";
import darkTheme from "../../themes/default"; // should be "../../theme/dark"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...