Material-UI Tooltip嵌套map函数时无法正常显示的问题求助
解决Material-UI Tooltip在表格行中无法单独显示专属内容的问题
看起来你遇到的核心问题是所有行共用了同一个open状态,而且Tooltip的内容是固定的,没法实现每行专属的提示效果。咱们一步步来修复:
核心问题分析
- 单个
open状态:点击任意按钮时,所有Tooltip都会响应这个状态,导致要么全显示要么全隐藏,没法单独控制某一行的Tooltip。 - 固定的Tooltip内容:当前
title是硬编码的字符串,没有关联每行的独特数据。
解决方案步骤
1. 调整状态管理
把单个open状态换成记录当前打开Tooltip的行标识(比如行的id或者索引),这样就能精准控制某一行的Tooltip显示:
// 替换原来的const [ open, setOpen ] = useState(false) const [ openTooltipRowId, setOpenTooltipRowId ] = useState(null)
2. 修改Tooltip的显示控制和内容
open属性:判断当前行的id是否等于openTooltipRowIdtitle:替换成当前行的专属内容,比如用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
相关产品推荐
相关产品推荐

