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

添加currentUser代码后Material-UI Tab指示器点击非首页标签时消失

问题原因

  • Material UI的<Tabs>组件要求直接子元素必须是<Tab>组件,你在判断currentUser显示不同Tab时外层包了<div>,导致Tabs无法正确统计Tab索引,指示器定位完全错乱
  • useEffect依赖项错误:你当前只监听了value,路径变化、currentUser变化时都不会触发同步逻辑,登录态切换后Tab的数量、对应索引发生变化,你写死的索引匹配规则也完全不适用
  • 登录/未登录状态下Tab的索引映射规则不一样,你没有区分两种状态做判断

修复方案

首先删掉Tab外层多余的div,用React.Fragment(简写<>)包裹,保证Tabs的直接子元素只有Tab;然后修正useEffect的依赖项,调整索引匹配逻辑适配不同登录态:

const Header = (props) => {
  const { currentUser } = props;
  const [value, setValue] = React.useState(0);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  // 修正useEffect依赖和索引匹配逻辑
  useEffect(() => {
    const path = window.location.pathname;
    // 首页固定对应索引0
    if (path === "/") {
      setValue(0);
      return;
    }
    // 区分登录态判断剩余Tab的索引
    if (currentUser) {
      // 登录态下Tab顺序:0=首页 1=个人资料
      if (path === "/profile") setValue(1);
    } else {
      // 未登录态下Tab顺序:0=首页 1=登录 2=注册
      if (path === "/login") setValue(1);
      else if (path === "/registration") setValue(2);
    }
  }, [currentUser, window.location.pathname]); // 依赖项改为登录态和访问路径

  const theme = useTheme();
  const isMatch = useMediaQuery(theme.breakpoints.down("md"));
  return (
    <div>
      <AppBar>
        <Toolbar variant="dense">
          {isMatch ? (
            <h1>
              <div>
                <DrawerComponent />
              </div>
            </h1>
          ) : (
            <div>
              <Grid>
                <Tabs
                  value={value}
                  indicatorColor="primary"
                  onChange={handleChange}
                  aria-label="simple tabs example"
                  variant="fullWidth"
                >
                  <Tab disableRipple label="Homepage" to="/" component={Link} />
                  {currentUser && (
                    <> {/* 替换原有div为Fragment,不会生成真实DOM节点,不影响Tabs识别子元素 */}
                      <Tab
                        disableRipple
                        label="Profile"
                        to="/profile"
                        component={Link}
                      />
                      <Button color="inherit" onClick={() => auth.signOut()}>
                        Logout
                      </Button>
                    </>
                  )}

                  {!currentUser && (
                    <> {/* 替换原有div为Fragment */}
                      <Tab
                        disableRipple
                        label="Login"
                        to="/login"
                        component={Link}
                      />
                      <Tab
                        disableRipple
                        label="Register"
                        to="/registration"
                        component={Link}
                      />
                    </>
                  )}
                </Tabs>
              </Grid>
            </div>
          )}
        </Toolbar>
      </AppBar>
    </div>
  );
};

Header.defaultProps = {
  currentUser: null,
};

const mapStateToProps = ({ user }) => ({
  currentUser: user.currentUser,
});

export default connect(mapStateToProps, null)(Header);

额外优化建议

你当前把退出登录的Button放在Tabs组件内部不符合组件规范,Button不会被识别为Tab,会导致索引计算多一位,建议把Button移到Tabs组件外面,和Tabs同级排列,避免后续出现额外的索引错乱问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:06:04