React如何在Header组件调用App.js的MUI主题切换函数
解决Header组件调用App中主题切换函数的问题
核心问题
子组件无法直接访问父组件的状态与函数,你需要通过props传递的方式,把App里的isDarkTheme状态和changeTheme函数传给Header组件,才能在Switch按钮中使用。
具体修改步骤
1. 修正App.js中的函数定义
函数式组件里不能用类组件的函数写法,把changeTheme改成标准的函数定义:
// 替换原有changeTheme代码 const changeTheme = () => { setIsDarkTheme(!isDarkTheme) }
2. 向Header组件传递props
在App.js的<Header>标签中,把状态和函数作为props传入:
<Header isDarkTheme={isDarkTheme} changeTheme={changeTheme} />
3. 在Header组件中接收并使用props
修改ResponsiveAppBar组件,先接收传入的props,再在Switch组件中调用:
// 组件定义时接收props const ResponsiveAppBar = ({ isDarkTheme, changeTheme }) => { // 别忘了导入useState,否则会报错 import { useState } from 'react' const [value, setValue] = useState(0) const theme = useTheme() const isMatch = useMediaQuery(theme.breakpoints.down('md')) return ( // 其余代码保持不变,仅修改Switch部分 <Switch checked={isDarkTheme} onChange={changeTheme} /> // 其余代码保持不变 ) }
完整修正后的代码
App.js
import { createTheme, ThemeProvider } from '@mui/material/styles' import Button from '@mui/material/Button' import Header from './components/Header' import About from './pages/About' import Imoveis from './pages/Imoveis' import Contact from './pages/Contact' import Home from './pages/Home' import { BrowserRouter, Routes, Route } from 'react-router-dom' import { CssBaseline } from '@mui/material' import { useState } from 'react' function App() { const light = { palette: { mode: 'light', }, } const dark = { palette: { mode: 'dark', }, } const [isDarkTheme, setIsDarkTheme] = useState(false) // 修正后的函数定义 const changeTheme = () => { setIsDarkTheme(!isDarkTheme) } return ( <ThemeProvider theme={isDarkTheme ? createTheme(dark) : createTheme(light)} > <div className="App"> <BrowserRouter> <CssBaseline /> {/* 传递状态与切换函数 */} <Header isDarkTheme={isDarkTheme} changeTheme={changeTheme} /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> <Route path="/imoveis" element={<Imoveis />} /> </Routes> </BrowserRouter> </div> </ThemeProvider> ) } export default App
Header组件(ResponsiveAppBar)
import AppBar from '@mui/material/AppBar' import Toolbar from '@mui/material/Toolbar' import Typography from '@mui/material/Typography' import Container from '@mui/material/Container' import { Link } from 'react-router-dom' import { Tabs, Tab, useTheme, useMediaQuery, Switch } from '@mui/material' import HouseIcon from '@mui/icons-material/House' import DrawerComp from './DrawerComp' // 导入useState import { useState } from 'react' // 接收父组件传入的props const ResponsiveAppBar = ({ isDarkTheme, changeTheme }) => { const [value, setValue] = useState(0) const theme = useTheme() const isMatch = useMediaQuery(theme.breakpoints.down('md')) return ( <AppBar position="static" sx={{ background: '#91060b' }}> <Container maxWidth="xl"> <Toolbar> <HouseIcon sx={{ transform: 'scale(2)' }} /> {isMatch ? ( <> <Typography sx={{ fontSize: '2rem', paddingLeft: '10%', fontWeight: 'bold', }} > NossoLar </Typography> <DrawerComp /> </> ) : ( <> <Tabs sx={{ marginLeft: 'auto' }} indicatorColor="secondary" textColor="inherit" value={value} onChange={(e, value) => setValue(value)} > <Tab label="Home" component={Link} to="/" /> <Tab label="Imoveis" component={Link} to="/imoveis" /> <Tab label="Sobre" component={Link} to="/about" /> <Tab label="Contato" component={Link} to="/contact" /> </Tabs> </> )} {/* 使用传递过来的状态与函数 */} <Switch checked={isDarkTheme} onChange={changeTheme} /> </Toolbar> </Container> </AppBar> ) } export default ResponsiveAppBar
额外提示
- 确认Header组件已导入
useState,否则会触发未定义错误 - Switch的
onChange默认会传递事件参数,当前逻辑直接切换状态已满足需求,无需额外处理
内容的提问来源于stack exchange,提问作者Marcela Silva
相关产品推荐
相关产品推荐

