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

React中使用MUI Grid组件布局如何避免元素重叠问题?

问题根因
  • MUI 内置的 <AppBar> 组件默认采用 position: fixed 定位,会脱离正常文档流,不会占用页面实际高度,因此下方的 Features 内容会从页面最顶部开始渲染,被悬浮的 AppBar 遮挡
  • 原有布局结构逻辑错误:PageHeader 是顶部通栏导航组件,不应该放置在左侧 3 列宽度的 Grid 容器中,需要独立置于页面最顶部
  • 侧边栏 Drawer 与主内容区均未预留与 AppBar 等高的顶部间距,导致多层组件重叠
完整修改方案

1. 修改 App.js,重构全局布局结构

import './App.css';
import { Grid, Box } from '@mui/material';
import SideMenu from './components/home/SideMenu';
import Features from './components/home/Features';
import PageHeader from './components/home/PageHeader';

// 统一管理侧边栏宽度,避免多文件重复定义
export const DRAWER_WIDTH = 240;

function App() {
  return (
    <Box sx={{ display: 'flex', width: '100%' }}>
      {/* 顶部通栏导航 */}
      <PageHeader />
      {/* 侧边菜单 */}
      <SideMenu />
      {/* 主内容区,预留顶部AppBar高度和左侧侧边栏宽度的边距 */}
      <Box
        component="main"
        sx={{
          flexGrow: 1,
          p: 3,
          marginTop: '64px', // 对应MUI默认Toolbar的高度,可通过theme变量适配响应式尺寸
          marginLeft: `${DRAWER_WIDTH}px`,
        }}
      >
        <Features />
      </Box>
    </Box>
  );
}

export default App;

2. 修改 PageHeader.js,调整AppBar适配逻辑

import * as React from 'react';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import { Grid } from '@mui/material';
import { DRAWER_WIDTH } from '../../App'; // 导入统一的侧边栏宽度

const LOGGED_IN = false

const getButtons = (isLogin) => {
    if (isLogin) {
        return <Grid container>
            <Grid item xs={7}></Grid>
            <Grid item xs={2} >
                <Button color="inherit">
                    <Typography variant="h6" component="div">
                        Profile
                    </Typography>
                </Button>
            </Grid>
            <Grid item xs={2} >
                <Button color="inherit">
                    <Typography variant="h6" component="div">
                        Logout
                    </Typography>
                </Button>
            </Grid>
        </Grid>
    }
    return <Grid container>
        <Grid item xs={9}></Grid>
        <Grid item xs={2}>
            <Button color="inherit">
                <Typography variant="h6" component="div">
                    Login
                </Typography>
            </Button>
        </Grid>
    </Grid>
}

export default function PageHeader(props) {
    return (
        <AppBar
            sx={{
                width: { sm: `calc(100% - ${DRAWER_WIDTH}px)` },
                ml: { sm: `${DRAWER_WIDTH}px` },
            }}
        >
            <Toolbar>
                <Grid item xs={4}>
                    <Typography variant="h3" component="div">
                        Stonks!
                    </Typography>
                </Grid>
                {getButtons(LOGGED_IN)}
            </Toolbar>
        </AppBar>
    );
}

3. 修改 SideMenu.js,简化冗余布局代码

import * as React from 'react';
import { Divider, Drawer, List, ListItem, ListItemIcon, ListItemText } from '@mui/material';
import { styled } from '@mui/material/styles';
import BusinessIcon from '@mui/icons-material/Business';
import ShowChartIcon from '@mui/icons-material/ShowChart';
import AppsIcon from '@mui/icons-material/Apps';
import SupervisedUserCircleIcon from '@mui/icons-material/SupervisedUserCircle';
import InfoIcon from '@mui/icons-material/Info';
import CreateIcon from '@mui/icons-material/Create';
import { DRAWER_WIDTH } from '../../App'; // 导入统一的侧边栏宽度

// 该组件高度默认与Toolbar等高,用于侧边栏顶部预留AppBar的位置
const DrawerHeader = styled('div')(({ theme }) => ({
    ...theme.mixins.toolbar,
}))

export default function SideMenu(props) {
    return (
        <Drawer
            sx={{
                width: DRAWER_WIDTH,
                flexShrink: 0,
                boxSizing: 'border-box',
                '& .MuiDrawer-paper': {
                    width: DRAWER_WIDTH,
                    boxSizing: 'border-box',
                },
            }}
            variant="persistent"
            anchor="left"
            open={true}
        >
            <DrawerHeader />
            <Divider />
            <List>
                {['Companies', 'Exchanges', 'Sectors', 'Users'].map((text) => (
                    <ListItem button key={text}>
                        <ListItemIcon>
                            {(() => {
                                switch (text) {
                                    case 'Companies':
                                        return <BusinessIcon />
                                    case 'Exchanges':
                                        return <ShowChartIcon />
                                    case 'Sectors':
                                        return <AppsIcon />
                                    case 'Users':
                                        return <SupervisedUserCircleIcon />
                                }
                            })()}
                        </ListItemIcon>
                        <ListItemText primary={text} />
                    </ListItem>
                ))}
            </List>
            <Divider />
            <List>
                {['About', 'Creators'].map((text) => (
                    <ListItem button key={text}>
                        <ListItemIcon>
                            {(() => {
                                switch (text) {
                                    case 'About':
                                        return <InfoIcon />
                                    case 'Creators':
                                        return <CreateIcon />
                                }
                            })()}
                        </ListItemIcon>
                        <ListItemText primary={text} />
                    </ListItem>
                ))}
            </List>
        </Drawer>
    );
}

Features.js、DisplayCard.js 无需修改即可正常使用,修改完成后所有组件不会再出现重叠问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 10:54:04