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

MUI Tabs指示器颜色刷新后恢复为全局主题主色问题求助

MUI Tabs指示器刷新后样式被覆盖问题

问题现象

用MUI实现的4个Tab标签页,页面刷新后Tab指示器颜色会恢复为全局主题中primary主色(白色)。无论直接在Tabs组件上设置样式,还是在全局主题里配置样式覆盖,首次设置均能生效,但刷新后样式就会被打回原形。临时在组件上重新添加样式可恢复预期效果,但刷新后问题依旧。

相关代码

导航栏组件代码

import { AppBar, Collapse, IconButton, Stack, Toolbar, Typography, useTheme } from '@mui/material';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import MenuIcon from '@mui/icons-material/Menu';
import TimerIcon from '@mui/icons-material/Timer';
import { useState } from 'react';
import LoginIcon from '@mui/icons-material/Login';
import { useNavigate } from 'react-router-dom';

const Header = () => {
    const [isSecondaryMenuOpen, setIsSecondaryMenuOpen] = useState<boolean>(false);
    const [tabValue, setTabValue] = useState<string>('newWorkout');
    const secondaryMenu = isSecondaryMenuOpen ? 4 : 5;
    const theme = useTheme();

    const navigate = useNavigate();
    const navigationHandler = (addedURL: string) => {
        navigate(addedURL);
    };

    return (
        <>
            <Stack sx={{ maxWidth: '100vW' }}>
                <AppBar
                    elevation={secondaryMenu}
                    color='primary'
                    position='static'
                    sx={{ bgcolor: theme.palette.primary.main }}
                >
                    <Toolbar>
                        <Stack
                            direction='row'
                            justifyContent='space-between'
                            alignItems='center'
                            sx={{ width: '100%' }}
                        >
                            <IconButton
                                size='large'
                                edge='start'
                                color='inherit'
                                aria-label='menu'
                                sx={{ mr: 1 }}
                                onClick={() => {
                                    setIsSecondaryMenuOpen(!isSecondaryMenuOpen);
                                }}
                            >
                                <MenuIcon sx={{ color: 'black' }} />
                            </IconButton>

                            <Stack sx={{ flexGrow: 1 }}>
                                <Typography
                                    variant='h5'
                                    component='div'
                                    sx={{ textAlign: 'center' }}
                                >
                                    Workout
                                </Typography>
                            </Stack>

                            <LoginIcon onClick={() => navigationHandler('/logged-out.html')} />
                        </Stack>
                    </Toolbar>
                </AppBar>
                <SecondaryHeader
                    open={isSecondaryMenuOpen}
                    value={tabValue}
                    onChange={(event: React.SyntheticEvent, newValue: string) => setTabValue(newValue)}
                />
            </Stack>
        </>
    );
};
export default Header;

function SecondaryHeader(props: {
    open: boolean;
    value: string;
    onChange: (event: React.SyntheticEvent, newValue: string) => void;
}) {
    const theme = useTheme();
    return (
        <Collapse
            in={props.open}
            timeout='auto'
            unmountOnExit
        >
            <AppBar
                sx={{ minHeight: '3vh', bgcolor: theme.palette.primary.main }}
                position='static'
                elevation={5}
            >
                <Stack
                    direction='row'
                    spacing={1}
                    width={'100%'}
                >
                    <Tabs
                        value={props.value}
                        onChange={props.onChange}
                        variant='scrollable'
                        scrollButtons='auto'
                    >
                        <Tab
                            label='New Workout'
                            value='newWorkout'
                        />
                        <Tab
                            label='Add Lift'
                            value='addLift'
                        />
                        <Tab
                            label='Calendar'
                            value='calendar'
                        />
                        <Tab
                            label='Analytics'
                            value='analytics'
                        />
                    </Tabs>
                </Stack>
            </AppBar>
        </Collapse>
    );
}

全局主题配置代码

import { createTheme, makeStyles } from '@mui/material';
import '@fontsource/staatliches';
import { Icon } from '@material-ui/core';
import { ThemeOptions } from '@mui/material/styles';

export const theme: ThemeOptions = {
    palette: {
        mode: 'light',
        primary: {
            main: '#FFFFFF',
            light: 'rgb(216,223,227)',
            dark: 'rgb(144,151,154)',
            contrastText: 'rgba(0,0,0,0.87)',
        },
        error: {
            main: '#d32f2f',
            light: '#ef5350',
            dark: '#c62828',
            contrastText: '#fff',
        },
        warning: {
            main: '#ed6c02',
            light: '#ff9800',
            dark: '#e65100',
            contrastText: '#fff',
        },
        info: {
            main: '#0288d1',
            light: '#03a9f4',
            dark: '#01579b',
            contrastText: '#fff',
        },
        success: {
            main: '#28a745',
            light: '#4caf50',
            dark: '#238b45',
            contrastText: '#fff',
        },
        text: {
            primary: 'rgba(0,0,0,0.87)',
            secondary: 'rgba(0,0,0,0.54)',
            disabled: 'rgba(0,0,0,0.38)',
        },
    },
    typography: {
        fontFamily: 'Staatliches, san-serif',
    },
    components: {
        MuiTabs: {
            styleOverrides: {
                root: {
                    fontWeight: 'bold',
                    '& .Mui-selected': {
                        color: '#B3A369',
                    },
                    '& .MuiTabs-indicator': {
                        backgroundColor: '#B3A369',
                        height: '3px',
                    },
                },
            },
        },
    },
};
export default createTheme(theme);

App组件代码

import ApplicationHeader from '../SharedComponents/ApplicationHeader';
import { CssBaseline, ThemeProvider } from '@mui/material';
import theme from '../GlobalStyles/GlobalStyles';
import NewWorkouts from '../authenticated/NewWorkout/NewWorkouts';
import { useState } from 'react';

function App() {
    const [accepted, setAccepted] = useState(false);
    const [authenticated, setAuthenticated] = useState(false);
    const [tabValue, setTabValue] = useState<string>('newWorkout');

    return (
        <div>
            <CssBaseline />
            <ApplicationHeader />
        </div>
    );
}

export default App;

效果对比

刷新后效果

聚焦选中Tab时的效果

添加临时样式后效果

添加的样式代码:

<Tabs
    value={props.value}
    onChange={props.onChange}
    variant='scrollable'
    scrollButtons='auto'
    sx={{
        '& .Mui-selected': {
            color: '#B3A369',
        },
    }}
>

添加样式后的效果

解决方案

1. 修复ThemeProvider包裹范围

你的App组件未用ThemeProvider包裹ApplicationHeader,导致全局主题样式根本没生效。修改App组件代码,将内容放入ThemeProvider中:

function App() {
    const [accepted, setAccepted] = useState(false);
    const [authenticated, setAuthenticated] = useState(false);
    const [tabValue, setTabValue] = useState<string>('newWorkout');

    return (
        <ThemeProvider theme={theme}>
            <CssBaseline />
            <ApplicationHeader />
        </ThemeProvider>
    );
}

这是核心问题——全局主题未被应用到组件,刷新后样式自然回退到默认值。

2. 提升样式优先级(可选)

若ThemeProvider配置正确后仍有问题,可通过以下方式提升样式优先级:

  • 全局主题中给样式添加!important(应急可用,不推荐长期使用):
components: {
    MuiTabs: {
        styleOverrides: {
            root: {
                fontWeight: 'bold',
                '& .Mui-selected': {
                    color: '#B3A369 !important',
                },
                '& .MuiTabs-indicator': {
                    backgroundColor: '#B3A369 !important',
                    height: '3px',
                },
            },
        },
    },
},
  • 组件内使用更精确的选择器:
<Tabs
    sx={{
        '& .MuiTabs-indicator': {
            backgroundColor: '#B3A369',
            height: 3,
        },
        '& .MuiTab-root.Mui-selected': {
            color: '#B3A369',
        }
    }}
    // 其他属性
>

3. 确认Tab的value类型匹配

确保tabValue的类型与Tab组件的value属性完全一致,避免因状态不匹配导致样式异常。当前代码使用字符串类型,匹配正常,后续修改需保持一致。

内容的提问来源于stack exchange,提问作者RogueGingerz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 15:12:00