在浏览器上/重新加载/或返回页面时如何使主题状态持久化?

德雷

当用户重新加载,访问新页面或在浏览器上按回鼠标等等时,如何使我的亮/暗主题永久保存为一种状态。...现在非常不一致。

这是我设置主题的index.js。我将其包裹在组件周围。

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>
            <MyThemeProvider>
                <CssBaseline />
                    <Header />
                    <Switch>
                        <Route exact path="/" component={App} />
                        <Route path="/register" component={Register} />
                        <Route path="/login" component={Login} />
                        <Route path="/logout" component={Logout} />
                        <Route path="/dash/:slug" component={Bucket} />
                        <Route path="/create" component={CreateBucket}/>
                    </Switch>
                    <Footer />
            </MyThemeProvider>
        </React.StrictMode>
    </Router>
);

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




我使用一个激活主题状态的开关,它位于我的标题中。 header.js

import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import CssBaseline from '@material-ui/core/CssBaseline';
import { makeStyles } from '@material-ui/core/styles';
import { NavLink } from 'react-router-dom';
import Link from '@material-ui/core/Link';
import Button from '@material-ui/core/Button';
import Switch from '@material-ui/core/Switch';
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;

如何解决状态不保存的矛盾?感谢您的帮助!

布扎托

您将使用localStorage密钥名将状态保留在内存中。在应用程序重新加载时,您的初始状态将来自存储在中的值localStorage,如果未设置,!!则将确保该值false不是null

同时传递给Provider更新状态并将新值设置的函数localStorage这样一来,您无需记住在localStorage消耗消耗的每个位置设置值setIsDarkMode

// if it's not set in localStorage value is null, then !! will set as false
const initialState = !!JSON.parse(localStorage.getItem('theme'))

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

  // you pass another function where you persist the value to localStorage
  // given your code you may just create a toggle function where you don't need to pass a value. but you can change it to receive an argument
  const toggleDarkMode = () => {
    setIsDarkMode(themeMode => {
      localStorage.setItem('theme', !themeMode)
      return !themeMode
    })
  }

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

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

然后Header您提取toggleDarkMode

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

    const {isDarkMode, toggleDarkMode} = useMyThemeContext();

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

export default Header;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

WordPress-如何更改浏览器加载页面时使用的主题文件?

来自分类Dev

Web开发:如何在浏览器中“存储”页面并防止每次浏览时都重新加载页面

来自分类Dev

使用浏览器刷新页面(F5)重新加载页面时,Odoo状态栏出现故障

来自分类Dev

asp.net c#强制在浏览器上重新加载页面打印热键

来自分类Dev

浏览器同步不会在监视任务完成时重新加载页面

来自分类Dev

浏览器同步不会在监视任务完成时重新加载页面

来自分类Dev

如何仅通过附加哈希值来重新加载浏览器页面?

来自分类Dev

浏览器保存的密码无法在页面加载时加载

来自分类Dev

如何在使用移动浏览器浏览器时防止从缓存中重新加载网页?

来自分类Dev

Angular Router在浏览器刷新时未重新加载

来自分类Dev

屏幕旋转时重新加载网络浏览器

来自分类Dev

使用ui路由器在AngularJS中的浏览器后退/前进按钮上重新加载页面

来自分类Dev

在OSX上,如何一次重新加载所有可见的浏览器窗口?

来自分类Dev

当用户在谷歌浏览器中按下后退按钮时,如何加载上次状态?

来自分类Dev

在“浏览器刷新”上加载特定页面。SPA AngularJS

来自分类Dev

页面加载时使Google Chrome浏览器全屏显示

来自分类Dev

尝试从Flask应用加载页面时浏览器挂起

来自分类Dev

在Safari中使用“浏览器后退”按钮时,从浏览器缓存中重新加载了Asp.net MVC视图/页面

来自分类Dev

为什么Google Chrome浏览器会在每次重新加载页面时增加内存使用量?

来自分类Dev

如何检测Selenium何时加载浏览器的错误页面

来自分类Dev

浏览器如何知道已加载多少页面?

来自分类Dev

在Flask上投放页面时,如何在浏览器中上传图像预览?

来自分类Dev

从iPad上的列表中卸载页面时,如何防止移动浏览器跳转?

来自分类Dev

重新加载页面后,浏览器要求重新发送数据

来自分类Dev

在Web浏览器上加载Java Applet时如何显示进度栏

来自分类Dev

当没有在初始页面上加载角度时,如何选择,用量角器的元素浏览器单击元素

来自分类Dev

当没有在初始页面上加载角度时,如何选择,用量角器的元素浏览器单击元素

来自分类Dev

angularjs:单击浏览器的后退按钮时如何从嵌套视图返回上一页?

来自分类Dev

如何重定向到特定浏览器上的页面?

Related 相关文章

  1. 1

    WordPress-如何更改浏览器加载页面时使用的主题文件?

  2. 2

    Web开发:如何在浏览器中“存储”页面并防止每次浏览时都重新加载页面

  3. 3

    使用浏览器刷新页面(F5)重新加载页面时,Odoo状态栏出现故障

  4. 4

    asp.net c#强制在浏览器上重新加载页面打印热键

  5. 5

    浏览器同步不会在监视任务完成时重新加载页面

  6. 6

    浏览器同步不会在监视任务完成时重新加载页面

  7. 7

    如何仅通过附加哈希值来重新加载浏览器页面?

  8. 8

    浏览器保存的密码无法在页面加载时加载

  9. 9

    如何在使用移动浏览器浏览器时防止从缓存中重新加载网页?

  10. 10

    Angular Router在浏览器刷新时未重新加载

  11. 11

    屏幕旋转时重新加载网络浏览器

  12. 12

    使用ui路由器在AngularJS中的浏览器后退/前进按钮上重新加载页面

  13. 13

    在OSX上,如何一次重新加载所有可见的浏览器窗口?

  14. 14

    当用户在谷歌浏览器中按下后退按钮时,如何加载上次状态?

  15. 15

    在“浏览器刷新”上加载特定页面。SPA AngularJS

  16. 16

    页面加载时使Google Chrome浏览器全屏显示

  17. 17

    尝试从Flask应用加载页面时浏览器挂起

  18. 18

    在Safari中使用“浏览器后退”按钮时,从浏览器缓存中重新加载了Asp.net MVC视图/页面

  19. 19

    为什么Google Chrome浏览器会在每次重新加载页面时增加内存使用量?

  20. 20

    如何检测Selenium何时加载浏览器的错误页面

  21. 21

    浏览器如何知道已加载多少页面?

  22. 22

    在Flask上投放页面时,如何在浏览器中上传图像预览?

  23. 23

    从iPad上的列表中卸载页面时,如何防止移动浏览器跳转?

  24. 24

    重新加载页面后,浏览器要求重新发送数据

  25. 25

    在Web浏览器上加载Java Applet时如何显示进度栏

  26. 26

    当没有在初始页面上加载角度时,如何选择,用量角器的元素浏览器单击元素

  27. 27

    当没有在初始页面上加载角度时,如何选择,用量角器的元素浏览器单击元素

  28. 28

    angularjs:单击浏览器的后退按钮时如何从嵌套视图返回上一页?

  29. 29

    如何重定向到特定浏览器上的页面?

热门标签

归档