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

如何从React Material UI组件(如ListItemText)中获取点击元素的值?

解决Material UI ListItemText点击内容获取失败的问题

这个问题我太熟啦!主要是因为Material UI的组件都是封装过的,你写的<ListItemText>在页面渲染后会变成多层嵌套的DOM元素,比如实际结构可能是这样的:

<div class="test MuiListItemText-root">
  <span class="MuiListItemText-primary">Date de naissance</span>
  <span class="MuiListItemText-secondary">1990-01-01</span>
</div>

你点击的时候,evt.target其实是里面的<span>标签,而不是你加了test类的那个根div,所以你原来用document.getElementById(evt.target.id)或者getElementsByClassName自然拿不到正确的内容。

给你三个靠谱的解决思路,从DOM操作到React原生写法都有:

思路一:通过closest()定位目标元素

利用DOM的closest()方法,从点击的目标元素往上找第一个带有test类的祖先元素,这样不管你点的是哪个子节点,都能精准定位到<ListItemText>对应的根DOM:

function traiteClick(evt) {
  // 找到最近的带test类的元素
  const targetElement = evt.target.closest('.test');
  if (targetElement) {
    // 分别获取primary和secondary的文本内容
    const primaryContent = targetElement.querySelector('.MuiListItemText-primary')?.textContent;
    const secondaryContent = targetElement.querySelector('.MuiListItemText-secondary')?.textContent;
    
    // 这里把内容传给你的Web组件展示
    console.log('标题:', primaryContent, '内容:', secondaryContent);
  }
}

这个方法不需要修改你的JSX,只需要调整事件处理函数就行,很灵活。

思路二:给ListItemText加自定义标识属性

如果你觉得用类名定位不够可靠,可以给<ListItemText>加一个自定义的data-*属性,比如data-component="list-item-text",这样定位更明确:

<ListItemText 
  className='test' 
  primary="Date de naissance" 
  secondary={artist?.lifeSpan?.begin}
  data-component="list-item-text"
/>

然后在事件处理函数里这样找:

function traiteClick(evt) {
  const targetElement = evt.target.closest('[data-component="list-item-text"]');
  if (targetElement) {
    // 同样获取内容
    const primaryContent = targetElement.querySelector('.MuiListItemText-primary')?.textContent;
    const secondaryContent = targetElement.querySelector('.MuiListItemText-secondary')?.textContent;
    // 处理展示逻辑
  }
}

自定义属性不会和样式冲突,也更语义化,后期维护起来更方便。

思路三:React原生写法(推荐)

既然用的是React,其实最符合React设计理念的方式是直接给<ListItemText>绑定点击事件,不需要在根容器做全局委托,这样能直接拿到组件的props内容,完全不用操作DOM:

// 定义点击处理函数
const handleListItemClick = (primary, secondary) => {
  // 直接拿到需要的内容,传给Web组件展示
  console.log('标题:', primary, '内容:', secondary);
};

// 在ListItemText上绑定事件
<ListItemText 
  className='test' 
  primary="Date de naissance" 
  secondary={artist?.lifeSpan?.begin}
  onClick={() => handleListItemClick("Date de naissance", artist?.lifeSpan?.begin)}
/>

这种方法完全避开了DOM结构变化的问题,因为你直接传递的是组件的props数据,而不是从DOM里去捞内容,代码也更清晰,后期改需求的时候更省心。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 14:48:10