使用 MUI V5 最新版本通过 React、Next JS 和本地存储切换暗模式

Posted

技术标签:

【中文标题】使用 MUI V5 最新版本通过 React、Next JS 和本地存储切换暗模式【英文标题】:Toggle Dark Mode with React, Next JS & Local Storage using MUI V5 Latest Version 【发布时间】:2021-12-25 19:58:51 【问题描述】:

目前,我正在开发一个使用NEXT JSMUI 5 最新版本以及GraphQL 构建的Web 应用程序。

我很赞同这一点:

我确实希望通过“https://mui.com/customization/dark-mode/#toggling-color-mode”使用此 MUI 指南的实现,同时在 LocalStorage 中保持不断变化的暗模式。

如果我切换开关然后将在 localStorage 中设置深色或浅色模式,是否有人可以指导我完成?我需要你的所有建议。

我正在使用 Context API

import  createContext, useMemo, useState  from 'react'
import  createTheme, ThemeProvider  from '@mui/material/styles'

// TODO: Export this one
export const ColorModeContext = createContext( toggleColorMode: () =>  )

const ThemeContext = ( children ) => 
    const [mode, setMode] = useState('dark')

    const colorMode = useMemo(
        () => (
            toggleColorMode: () => 
                setMode((prevMode) => (prevMode === 'light' ? 'dark' : 'light'))
            ,
        ),
        []
    )

    const theme = useMemo(
        () =>
            createTheme(
                palette: 
                    mode,
                    primary: 
                        light: '#757ce8',
                        main: '#3f50b5',
                        dark: '#002884',
                        contrastText: '#fff',
                    ,
                    secondary: 
                        light: '#ff7961',
                        main: '#f44336',
                        dark: '#ba000d',
                        contrastText: '#000',
                    ,
                ,
            ),
        [mode]
    )

    return (
        <ColorModeContext.Provider value=colorMode>
            <ThemeProvider theme=theme>children</ThemeProvider>
        </ColorModeContext.Provider>
    )


export default ThemeContext

我在我的 AppBar 中实现了这样的功能

// * ___main_appbar_function___
export default function MyAppBar(props) 
    const theme = useTheme()
    const colorMode = useContext(ColorModeContext)

    return (
        <NoSsr>
            <CssBaseline />
            <HideOnScroll ...props>
                <AppBar color='inherit'>
                    <Toolbar variant='dense' component='div'>
                        <Box sx=root>
                            <MySideBar />
                            <Typography component='div' variant='h5' textAlign='center'>
                                PJK
                            </Typography>
                            <Box sx=right>
                                /* <AuthModal /> */
                                <motion.div
                                    whileTap= rotate: 360 
                                    // whileHover= rotate: 360 
                                    transition= type: 'spring', stiffness: 50 
                                >
                                    <IconButton onClick=refreshPage>
                                        <RotateRightIcon />
                                    </IconButton>
                                </motion.div>

                                <IconButton
                                    sx= ml: 1 
                                    onClick=colorMode.toggleColorMode
                                    color='inherit'
                                >
                                    theme.palette.mode === 'dark' ? (
                                        <Brightness7Icon />
                                    ) : (
                                        <Brightness4Icon />
                                    )
                                </IconButton>
                            </Box>
                        </Box>
                    </Toolbar>
                </AppBar>
            </HideOnScroll>
            <Toolbar />
        </NoSsr>
    )

【问题讨论】:

【参考方案1】:

试试这个

const MODE = "mode";

const [mode, setMode] = useState(() => 

    // for the sake of solving this issues
   // ("ReferenceError: localStorage is not defined")
    if (typeof window !== 'undefined') 
        localStorage.getItem(MODE) || 'dark'
    
);

const colorMode = useMemo(
    () => (
        toggleColorMode: () => 
            setMode(prevMode => 
                const nextMode = prevMode === "light" ? "dark" : "light";
                localStorage.setItem(MODE, nextMode);
                return nextMode;
            );
        
    ),
    []
);

【讨论】:

@Chen Lay,看看这个!! 感谢代码,但它没有达到我的预期。你有什么其他的建议? localStorage 作为键和值成功插入到存储选项卡中。但是,切换按钮后主题不会保持持久性

以上是关于使用 MUI V5 最新版本通过 React、Next JS 和本地存储切换暗模式的主要内容,如果未能解决你的问题,请参考以下文章

React开发中使用react-router-dom路由最新版本V5.1.2基本跳转属性

React开发中使用react-router-dom路由最新版本V5.1.2基本跳转属性

React开发中使用react-router-dom路由最新版本V5.1.2路由嵌套子路由

React开发中使用react-router-dom路由最新版本V5.1.2路由嵌套子路由

最新版 react-navigation v5.0 上带有标题按钮的换屏

MUI v5 使用 styled() 将道具传递给 CSS 主题