React搭配Material UI实现明暗模式切换及发布按钮样式适配问题
解决方案
你需要完成「状态透传」和「样式动态适配」两部分修改,具体步骤如下:
1. 主题切换逻辑改造(替换Switch为Navbar按钮控制)
修改App.js
删除原有Switch组件,将主题状态和切换方法透传给子组件:
// App.js 完整修改后代码 import './App.css'; import React, {useState} from 'react'; import Body from './Body'; import Sidebar from './Sidebar'; import { makeStyles, ThemeProvider } from '@material-ui/core/styles'; import { createMuiTheme, CssBaseline } from '@material-ui/core'; const useStyles = makeStyles((theme) => ({ root: { width: "1440px", display: "flex", } })); function App() { const classes = useStyles(); const [darkMode, setDarkMode] = useState(false); const theme = createMuiTheme({ palette: { type: darkMode ? "dark" : "light", } }) const handleDarkMode = (mode) => { // 适配Navbar传入的固定模式值,兼容原有切换逻辑 setDarkMode(typeof mode === 'boolean' ? mode : !darkMode); } return ( <ThemeProvider theme={theme}> <CssBaseline> <div className={classes.root}> <Sidebar /> {/* 透传状态和方法给Body */} <Body darkMode={darkMode} toggleDarkMode={handleDarkMode} /> </div> </CssBaseline> </ThemeProvider> ); } export default App;
修改Body.js
接收透传的属性,继续传给Navbar组件:
// Body.js 修改后代码 import React from 'react'; import Navbar from './Navbar'; import { makeStyles } from '@material-ui/core/styles'; import Builder from './Builder'; const useStyles = makeStyles((theme) => ({ root: { width: "1180px", height: "100%", padding: "15px", } })); function Body(props) { const classes = useStyles(); return ( <div className={classes.root}> {/* 透传属性给Navbar */} <Navbar darkMode={props.darkMode} toggleDarkMode={props.toggleDarkMode} /> <Builder /> </div> ) } export default Body
2. Navbar功能与样式适配
修改Navbar的按钮逻辑、发布按钮动态样式:
// Navbar.js 完整修改后代码 import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Brightness4Icon from '@material-ui/icons/Brightness4'; import Brightness7Icon from '@material-ui/icons/Brightness7'; import Button from '@material-ui/core/Button'; import OpenInNewIcon from '@material-ui/icons/OpenInNew'; const useStyles = makeStyles((theme) => ({ root: { display: "flex", justifyContent: "space-between" }, leftNav: { justifyContent: "center", alignItems: "center", borderRadius: "12px", }, lightMode:{ justifyContent: "center", alignItems: "center", border: "none", fontSize: "15px", padding: "10px", borderRadius: "12px", textTransform: "none", }, darkMode:{ justifyContent: "center", alignItems: "center", border: "none", fontSize: "15px", padding: "10px", borderRadius: "12px", textTransform: "none", }, // 新增选中模式按钮高亮样式 activeMode: { backgroundColor: theme.palette.action.selected, }, rightNav: { justifyContent: "center", alignItems: "center", marginTop: "10px", }, preview:{ marginRight: "15px", textDecoration: "none", justifyContent: "center", alignItems: "center", fontSize: "13px", "&:hover": { textDecoration: "underline", } }, publish:{ marginLeft: "15px", textDecoration: "none", // 动态适配主题色 backgroundColor: theme.palette.type === 'light' ? "#02AA02" : "#017a01", color: "white", padding: "12px", paddingLeft: "18px", paddingRight: "18px", borderRadius: "18px", fontSize: "13px", }, icons: { marginRight: "8px", } })); function Navbar(props) { const classes = useStyles(); return ( <div className={classes.root}> <div className={classes.leftNav}> <Button variant="text" color="default" className={`${classes.lightMode} ${!props.darkMode ? classes.activeMode : ''}`} // 点击切换为亮色模式 onClick={() => props.toggleDarkMode(false)} > <Brightness7Icon className={classes.icons} /> 亮色模式 </Button> <Button variant="text" color="default" className={`${classes.darkMode} ${props.darkMode ? classes.activeMode : ''}`} // 点击切换为暗色模式 onClick={() => props.toggleDarkMode(true)} > <Brightness4Icon className={classes.icons} /> 暗色模式 </Button> </div> <div className={classes.rightNav}> <a href="#" className={classes.preview}> 新标签页预览 <OpenInNewIcon fontSize="small" style={{fontSize: "15px", marginLeft: "5px"}} /> </a> <a href="#"className={classes.publish}>发布网站</a> </div> </div> ) } export default Navbar
修改完成后即可实现两个需求:Navbar的两个按钮控制主题切换,发布按钮背景色会自动跟随明暗主题切换。
内容的提问来源于stack exchange,提问作者Racer User
相关产品推荐
相关产品推荐

