React+MUI子Layout组件实现暗色模式切换状态不生效该如何解决
问题原因
- 父组件App传参错误:
{...darkMode}是对布尔值做展开,无法正确把darkMode状态传递给Layout组件,同时也没有传递修改全局darkMode的setDarkMode方法 - Layout组件维护了独立的局部状态:点击开关修改的是Layout内部的
darkMode,无法触发父组件darkMode更新,因此ThemeProvider绑定的theme不会发生变化,全局主题自然不会切换
解决方案
修改App.js
修正参数传递逻辑,把全局状态和修改方法都传递给Layout组件:
// App.js (incl. routes and react-router-dom) import { useState } from 'react' // MUI v4导入路径为 @material-ui/core/styles import { createTheme, ThemeProvider } from '@mui/material/styles' const App = () => { const [ darkMode, setDarkMode ] = useState(false) const theme = createTheme({ palette: { // MUI v5版本请把type改为mode type: darkMode ? "dark" : "light" , } }) return ( <ThemeProvider theme={theme}> {/* 其他外层组件 */} <Layout darkMode={darkMode} setDarkMode={setDarkMode}> {/* 路由子组件等内容 */} </Layout> </ThemeProvider> ) } export default App
修改Layout.js
删除冗余的局部状态和useEffect,直接使用父组件传递的全局状态和修改方法:
import { Switch } from '@mui/material' import { useTheme } from '@mui/material/styles' const Layout = (props) => { const theme = useTheme() // 其他业务逻辑 return ( <> {/* 其他Layout渲染内容 */} <Switch checked={props.darkMode} onChange={() => props.setDarkMode(prev => !prev)} /> {props.children} </> ) } export default Layout
如果需要刷新页面后保留暗色模式状态,可以在App.js初始化状态时从localStorage取值,状态变化时同步存入localStorage即可。
内容的提问来源于stack exchange,提问作者Horkos
相关产品推荐
相关产品推荐

