You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:50:28