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

Material-UI Tooltip嵌套map函数时无法正常显示的问题求助

解决Material-UI Tooltip在表格行中无法单独显示专属内容的问题

看起来你遇到的核心问题是所有行共用了同一个open状态,而且Tooltip的内容是固定的,没法实现每行专属的提示效果。咱们一步步来修复:

核心问题分析

  1. 单个open状态:点击任意按钮时,所有Tooltip都会响应这个状态,导致要么全显示要么全隐藏,没法单独控制某一行的Tooltip。
  2. 固定的Tooltip内容:当前title是硬编码的字符串,没有关联每行的独特数据。

解决方案步骤

1. 调整状态管理

把单个open状态换成记录当前打开Tooltip的行标识(比如行的id或者索引),这样就能精准控制某一行的Tooltip显示:

// 替换原来的const [ open, setOpen ] = useState(false)
const [ openTooltipRowId, setOpenTooltipRowId ] = useState(null)

2. 修改Tooltip的显示控制和内容

  • open属性:判断当前行的id是否等于openTooltipRowId
  • title:替换成当前行的专属内容,比如用row.description或者拼接行内数据
  • 点击事件:打开时传入当前行的id,关闭时重置状态

3. 调整事件处理函数

更新handleTooltipOpen和handleTooltipClose:

const handleTooltipOpen = (rowId) => {
  setOpenTooltipRowId(rowId)
}

const handleTooltipClose = () => {
  setOpenTooltipRowId(null)
}

修改后的完整代码示例

function Home({ /* ... */ }) {
  const [ order, setOrder ] = useState('asc')
  const [ orderBy, setOrderBy ] = useState('id')
  // 替换原有open状态,记录当前打开tooltip的行id
  const [ openTooltipRowId, setOpenTooltipRowId ] = useState(null)
  const classes = useStyles()
  // 假设rows是包含每行数据的数组,比如[{id:1, description:"交易1", ...}, ...]
  const rows = []

  const handleTooltipOpen = (rowId) => {
    setOpenTooltipRowId(rowId)
  }

  const handleTooltipClose = () => {
    setOpenTooltipRowId(null)
  }

  return (
    <TableBody>
      { stableSort(rows, getComparator(order, orderBy))
        .map((row, index) => {
          const labelId = `enhanced-table-checkbox-${index}`
          // 判断当前行是否要显示tooltip
          const isTooltipOpen = openTooltipRowId === row.id
          return (
            <TableRow key={row.id}> {/* 务必添加唯一key */}
              <TableCell component="th" scope="row" padding="none">
                <ClickAwayListener onClickAway={ handleTooltipClose }>
                  <Tooltip 
                    arrow 
                    PopperProps={ { disablePortal: true, } } 
                    onClose={ handleTooltipClose } 
                    open={ isTooltipOpen } 
                    disableFocusListener 
                    disableHoverListener 
                    disableTouchListener 
                    {/* 这里换成当前行的专属内容 */}
                    title={`交易详情:ID ${row.id},金额 ${row.amount}`} 
                  >
                    <div>
                      <button 
                        onClick={ () => handleTooltipOpen(row.id) } 
                        className={ styles.tooltip } 
                      >
                        <img src='./eye-tooltip-button.png' className={ styles.tooltipImg } height='12px' width='12px' />
                      </button>
                    </div>
                  </Tooltip>
                </ClickAwayListener>
              </TableCell>
              <TableCell id={ labelId } align="right" size='small'>
                { row.id }
              </TableCell>
              <TableCell align="right" size='small'>{ row.description }</TableCell>
              <TableCell align="right" size='small'>{ row.amount }</TableCell>
              <TableCell align="right" size='small'>{ row.isCredit }</TableCell>
              <TableCell align="right" size='small' style={ { whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden', maxWidth: '1px' } } >
                { row.date }
              </TableCell>
              <TableCell align="right" size='small' style={ { whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden', maxWidth: '1px' } } >
                { row.imageUrl }
              </TableCell>
            </TableRow>
          )
        }) }
    </TableBody>
  )
}

关键改动说明

  • 状态区分:用openTooltipRowId记录当前打开Tooltip的行ID,实现了单行精准控制
  • 内容专属:Tooltip的title绑定当前行的row数据,确保每行显示独特内容
  • 事件传递:点击按钮时把当前行ID传给handleTooltipOpen,明确指定要打开哪一行的Tooltip
  • Key优化:给TableRow添加了基于row.id的唯一key,符合React列表渲染的最佳实践

这样调整后,点击每行的按钮就只会显示该行的专属Tooltip,点击别处就会关闭,完全符合你想要的Etherscan交易表类似效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:36:49