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

MUI Avatar组件Hover时弹出Card组件出现闪烁问题求助

问题分析与解决

闪烁原因

你遇到的闪烁问题不是key的问题,核心原因有两个:

  • Card显示时会占据文档流空间,导致布局移位,鼠标意外离开Avatar触发onMouseOut;Card消失后布局复原,鼠标又回到Avatar触发onMouseOver,循环往复造成闪烁。
  • 鼠标从Avatar移到弹出的Card上时,会触发Avatar的onMouseOut事件,直接清空hoveredEmployee,导致Card瞬间消失。

解决方案

1. 改用容器级hover事件

把onMouseEnter和onMouseLeave绑定到包裹Avatar和Card的外层div上,这样鼠标移到Card上时,不会触发离开事件(因为Card属于容器内部元素)。

2. 给Card设置绝对定位

让Card脱离文档流,避免显示/隐藏时改变页面布局,彻底解决移位导致的闪烁问题。

修改后的完整代码

import { Avatar, Card, CardContent, Grid, Paper, Typography } from '@mui/material';
import React, { useState, useMemo } from 'react';
import { FunctionComponent, ReactElement } from 'react';

export const People: FunctionComponent = (): ReactElement => {
  const [hoveredEmployee, setHoveredEmployee] = useState<string | null>(null);

  // 补全原代码缺失的数据源示例
  const employeeDetails = [{ loginName: 'sammy', fullName: 'sammy chung' }];
  const employeeDetailsMapped = { sammy: { loginName: 'smy', fullName: 'sammy chung' } };

  // 用useMemo优化分组逻辑,避免重复计算
  const groupedUsers = useMemo(() => {
    const groups: Record<string, string[]> = {};
    employeeDetails.forEach((item) => {
      const firstLetter = item.loginName.charAt(0).toUpperCase();
      if (!groups[firstLetter]) {
        groups[firstLetter] = [item.loginName];
      } else {
        groups[firstLetter].push(item.loginName);
      }
    });
    return groups;
  }, [employeeDetails]);

  return (
    <>
      <Grid container spacing={2}>
        <Paper elevation={2} sx={{ p: 3, my: 2, width: '100%', overflowY: 'auto', maxHeight: 600 }}>
          {Object.entries(groupedUsers).map(([letter, names]) => (
            <Grid item key={letter} sx={{ borderBottom: '1px solid #ddd', pb: 2, mb: 2 }}>
              <h3>{letter}</h3>
              {names.map((name: string) => (
                <div 
                  key={name} 
                  style={{ 
                    display: 'inline-block', 
                    marginRight: 10,
                    position: 'relative', // 作为Card绝对定位的父容器
                  }}
                  onMouseEnter={() => setHoveredEmployee(name)}
                  onMouseLeave={() => setHoveredEmployee(null)}
                >
                  <Avatar
                    variant='rounded'
                    alt={`Photo of ${employeeDetailsMapped[name].loginName}`}
                    src={`...`}
                    sx={{ height: 80, width: 80, mr: 2 }}
                  />
                  {hoveredEmployee === name && (
                    <Card
                      elevation={3}
                      sx={{
                        padding: 2,
                        height: 'auto',
                        width: '480px',
                        position: 'absolute', // 脱离文档流,避免布局移位
                        top: 0,
                        left: '100%', // 显示在Avatar右侧
                        ml: 2,
                        zIndex: 1000, // 确保Card在最上层
                        ':hover': {
                          boxShadow: 20,
                        },
                      }}
                    >
                      <CardContent>
                        <div style={{ display: 'flex', alignItems: 'center' }}>
                          <Avatar
                            variant='rounded'
                            alt={`Badge photo for ${employeeDetailsMapped[name].loginName}`}
                            src={`...`}
                            sx={{ height: 130, width: 130 }}
                          />
                          <Typography variant='h5' fontWeight={500} marginLeft={3}>
                            {employeeDetailsMapped[name].fullName}
                          </Typography>
                        </div>
                      </CardContent>
                    </Card>
                  )}
                </div>
              ))}
            </Grid>
          ))}
        </Paper>
      </Grid>
    </>
  );
};

额外优化说明

  • 用useMemo包裹分组逻辑,避免组件每次渲染都重复计算分组,提升性能。
  • 修正了原代码中employeeDetails未定义的问题,补全了示例数据源。
  • 调整了Card内的布局样式,让内容对齐更合理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:41:23