簡體   English   中英

當當前主題存儲在本地時,如何在淺色和深色主題之間切換?

[英]How do you toggle between light and dark themes while current theme is being locally stored?

我對反應還很陌生,我正在使用 Material-UI 實現一些新功能。我正在嘗試在淺色和深色主題之間切換,同時當前主題本地存儲在瀏覽器中。 我希望在頁面刷新時在本地存儲當前主題。 默認情況下,我的應用加載淺色主題。 在切換開關之前,我驗證了淺色主題是否在本地存儲中。 當我切換到深色主題時,我的應用程序更改為對應的應用程序,本地存儲中的值也按預期更改。 但是當我嘗試將開關切換回淺色主題時,主題沒有改變,只是我的本地存儲值。 我不知道為什么。

如果有人有辦法調整此代碼來解決此問題或提出新想法,我將不勝感激。

CodeSandbox 中的演示

CustomThemeContext.js

import React, { useState, createContext } from 'react';
import { ThemeProvider } from '@material-ui/core/styles';
import getTheme from '../components/MyThemes';
import Paper from '@material-ui/core/Paper';

export const CustomThemeContext = createContext(
  {
    currentTheme: 'normalTheme',
    setTheme: null,
  },
);

const CustomThemeProvider = (props) => {
  const { children } = props
  const currentTheme = localStorage.getItem('appTheme') || 'normalTheme'
  const [themeName, _setThemeName] = useState(currentTheme)
  const theme = getTheme(themeName)
  const setThemeName = (name) => {
    localStorage.setItem('appTheme', name)
    _setThemeName(name)
  }
  const contextValue = {
    currentTheme: themeName,
    setTheme: setThemeName,
  }
  const paperStyle = {
    height: "100vh",
  }

  return (
    <div>
      <CustomThemeContext.Provider value={contextValue}>
        <ThemeProvider theme={theme}>
          <Paper style={paperStyle}>
            {children}
          </Paper>
        </ThemeProvider>
      </CustomThemeContext.Provider>
    </div>
  )
}

export default CustomThemeProvider;

索引.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import CustomThemeProvider from './contexts/CustomThemeProvider';

ReactDOM.render(
  <React.StrictMode>
    <CustomThemeProvider>
      <App />
    </CustomThemeProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

serviceWorker.unregister();

應用程序.js

import React, { useContext } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { CustomThemeContext } from './contexts/CustomThemeProvider';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Tooltip from '@material-ui/core/Tooltip';
import Typography from '@material-ui/core/Typography';
import BurgerButton from './components/BurgerButton';
import StarButton from './components/StarButton';
import Switch from '@material-ui/core/Switch';
import Button from '@material-ui/core/Button';
import AddCircleIcon from '@material-ui/icons/AddCircle';
import FormControlLabel from '@material-ui/core/FormControlLabel';

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
    width: 'auto',
  },
  title: {
    flexGrow: 1,
  },
  content: {
    flexGrow: 1,
    padding: theme.spacing(3),
  }
}));

export default function App() {
  const classes = useStyles();
  const { currentTheme, setTheme } = useContext(CustomThemeContext);
  const isDark = Boolean(currentTheme === 'darkTheme')

  const handleThemeChange = (event) => {
    const { checked } = event.target
    if (checked) {
      setTheme('darkTheme')
    } else {
      setTheme('normalTheme')
    }
  }

  /*
  switch (checked) {
    case 'darkTheme':
      return setTheme('darkTheme');
    case 'normalTheme':
      return setTheme('normalTheme');
    default:
      return null;
  }
  */

  return (
    <div className="App">
      <div className={classes.root}>
        <AppBar position="static" title="Memo App">
          <Toolbar>
            <BurgerButton />
            <Typography variant="h6" className={classes.title}>
              Memo App
            </Typography>
            <Tooltip title="Toggle light theme/dark theme">
              <FormControlLabel
                control={<Switch checked={isDark} onChange={handleThemeChange} />}
                label="Theme"
              />
            </Tooltip>
            <StarButton />
          </Toolbar>
        </AppBar>
        <Button>
          <AddCircleIcon />
        </Button>
      </div>
    </div>
  );
}

我的主題.js

import normalTheme from './themes/normalTheme';
import darkTheme from './themes/darkTheme';

const themes = {
  normalTheme,
  darkTheme,
}

export default function getTheme(theme) {
  return themes[theme]
}

在您的ThemeProvider組件theme道具上,克隆您分配給它的主題 object 它應該可以工作

<ThemeProvider theme={{...theme}}>
  <Paper style={paperStyle}>
    {children}
  </Paper>
</ThemeProvider>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM