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

React+MUI Popper问题:点击按钮应显示对应人员城市而非全部

问题解决:MUI Popper显示全部数据而非当前行专属数据

核心问题是你所有行的Popper共用了同一组状态和数据源,导致点击任意按钮都会渲染全部城市。按下面的步骤调整就能解决:

1. 给每行维护独立的弹窗状态

不要用单一的open变量控制所有弹窗,改用对象存储每行的打开状态,键用人员的唯一ID:

const [rowPopups, setRowPopups] = useState({});
// 结构示例:{ personId1: true, personId2: false }

2. 点击按钮时绑定当前行数据

点击"Show addresses"时,切换对应行的弹窗状态,同时确保弹窗只渲染当前行的城市:

const togglePopup = (personId, city) => {
  setRowPopups(prev => ({
    ...prev,
    [personId]: !prev[personId]
  }));
};

3. 修正Popper的渲染逻辑

在表格行中,Popper的open属性绑定当前行的状态,内容直接用当前行的城市数据:

<TableBody>
  {people.map(person => (
    <TableRow key={person.id}>
      <TableCell>{person.name}</TableCell>
      <TableCell>
        <Button
          ref={el => (person.anchorEl = el)} // 给当前按钮绑定锚点引用
          onClick={() => togglePopup(person.id)}
        >
          Show addresses
        </Button>
        <Popper
          open={!!rowPopups[person.id]}
          anchorEl={person.anchorEl}
          placement="bottom-start"
        >
          <Paper sx={{ p: 2 }}>
            <Typography>{person.city}</Typography>
          </Paper>
        </Popper>
      </TableCell>
    </TableRow>
  ))}
</TableBody>

额外提示

  • 如果你的城市数据是通过GraphQL批量获取的,记得提前用人员ID建立映射(比如const cityMap = new Map(peopleData.map(p => [p.id, p.city]))),这样能快速拿到对应行的城市。
  • 锚点元素一定要绑定当前行的按钮,别共用同一个ref,不然弹窗会跟着最后一行的按钮走。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:27:49