如何为React+Material UI网页高效实现深色模式切换功能
优化方案
你当前的实现存在严重的代码冗余问题,后续维护成本极高,完全可以利用Material UI自带的主题能力实现深色模式切换,无需维护两套组件。
核心优化思路
Material UI的ThemeProvider已经将主题状态全局注入到所有子组件中,只要组件内部的样式从主题变量中取值,切换主题时所有样式会自动更新,不需要单独维护两套组件代码。
具体改造步骤
- 第一步:删除所有后缀为2的重复组件,只保留一份基础组件
- 第二步:改造所有组件内部的样式定义,将写死的颜色值替换为主题变量取值
示例(以Header组件为例):
改造前的样式:
改造后的样式:const useStyles = makeStyles({ headerTitle: { color: '#333', backgroundColor: '#fff' } })
你也可以在创建主题时自定义专属的颜色字段,之后在所有组件中直接调用即可。const useStyles = makeStyles((theme) => ({ headerTitle: { // 直接从主题调色板取对应场景的颜色,主题切换时自动更新 color: theme.palette.text.primary, backgroundColor: theme.palette.background.paper } })) - 第三步:简化Landing组件的逻辑,删除冗余的双分支返回结构
改造后的Landing组件代码
import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import CssBaseline from '@material-ui/core/CssBaseline'; import Switch from '@material-ui/core/Switch'; import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; import Header from '../Landing Page/components/Header/Header'; import StickyHeader from '../Landing Page/components/Header/StickyHeader'; import ProductSection from '../Landing Page/components/Product/ProductSection'; import HardwareSection from '../Landing Page/components/HardwareSection/HardwareSection'; import DashboardSection from '../Landing Page/components/DashboardSection/DashboardSection'; import MarketplaceSection from '../Landing Page/components/MarketplaceSection/MarketplaceSection'; import CustomModelSection from '../Landing Page/components/CustomModelSection/CustomModelSection'; import CommunicationSection from '../Landing Page/components/CommunicationSection/CommunicationSection'; import TableSection from '../Landing Page/components/TableSection/TableSection'; import PartnerSection from '../Landing Page/components/PartnerSection/PartnerSection'; import GetStarted from '../Landing Page/components/Bottom/GetStarted'; import Footer from '../Landing Page/components/Bottom/Footer'; const useStyles = makeStyles((theme) => ({ root: { minHeight: '100vh', backgroundImage: "url('https://wallpaperaccess.com/full/2180654.jpg')", backgroundRepeat: 'no-repeat', backgroundSize: 'contain', }, dark: { minHeight: '100vh', backgroundImage: "url('https://wallpaperaccess.com/full/1685406.jpg')", backgroundRepeat: 'no-repeat', backgroundSize: 'contain', }, })); export default function Landing() { const [darkPage, setDarkPage] = React.useState(false); // 可选优化:从localStorage读取用户上次的主题偏好 // const [darkPage, setDarkPage] = React.useState(localStorage.getItem('darkMode') === 'true'); const darkScheme = createMuiTheme({ palette: { type: darkPage ? 'dark' : 'light', // 这里可以自定义深色/浅色模式下的专属色值 }, }); const handleChange = () => { setDarkPage(prev => { const newVal = !prev // 可选优化:存储用户主题偏好到本地 // localStorage.setItem('darkMode', newVal) return newVal }); }; const classes = useStyles(); return ( <ThemeProvider theme={darkScheme}> <div className={darkPage ? classes.dark : classes.root}> <CssBaseline /> <Header /> <Switch checked={darkPage} onChange={handleChange} /> <StickyHeader /> <ProductSection /> <HardwareSection /> <DashboardSection /> <MarketplaceSection /> <CustomModelSection /> <CommunicationSection /> <TableSection /> <PartnerSection /> <GetStarted /> <Footer /> </div> </ThemeProvider> ); }
可选拓展优化
如果你的项目有多个页面需要支持深色模式,可以把主题状态抽到上层Context中全局维护,避免每个页面单独声明状态。
内容的提问来源于stack exchange,提问作者VinceMan54321
相关产品推荐
相关产品推荐

