React将点击处理函数作为prop传递时,父组件如何识别被点击的子组件
问题解决方法
核心问题在于依赖DOM属性读取标识的方式容易受点击目标、事件冒泡影响,更符合React设计逻辑的方案是直接在事件触发时传递标识参数,无需读取DOM属性,具体修改步骤如下:
方案1:直接传递标识参数(最推荐,无DOM依赖)
第一步:修改子组件点击事件绑定
在子组件ProjectCard的两个article标签的onClick回调中,直接把需要的标识(索引、项目ID等)作为参数传给父组件传入的处理函数:
// 两个article的onClick都按这个格式修改 onClick={(e) => handleClick(e, index, project)}
第二步:修改父组件处理函数,更新状态
父组件的handleClick直接接收子组件传递的参数,无需读取DOM属性:
const handleClick = (e, index, project) => { console.log(`点击的项目索引:${index},项目ID:${project.id}`) // 示例:实现点击对应项目展开、其余项目收起的互斥效果 setToggleObject(prevState => { const newToggleState = {} Object.keys(prevState).forEach(projectKey => { newToggleState[projectKey] = projectKey === project.id }) return newToggleState }) // 如果需要点击切换当前项目展开/收起,其他项目状态不变,用下面的更新逻辑即可 // setToggleObject(prevState => ({ // ...prevState, // [project.id]: !prevState[project.id] // })) }
方案2:修复dataset读取逻辑(可选)
如果坚持要通过DOM属性读取标识,需要注意e.target指向实际被点击的子元素(比如标题、图片),这些元素没有设置data-id,所以读取不到,调整方法如下:
- 子组件绑定
data-id时统一转成字符串:
<article className="single-project" data-id={String(index)} onClick={(e) => handleClick(e)}>
- 父组件处理函数中先找到绑定了
data-id的外层article元素:
const handleClick = (e) => { const targetArticle = e.target.closest('article.single-project') const clickIndex = targetArticle.dataset.id console.log('点击的项目索引:', clickIndex) }
额外优化建议
列表渲染的key不要用index,换成project.id这类唯一固定值,避免数组顺序变化时出现渲染异常:
<ProjectCard toggled={toggleObject[project]} key={project.id} project={ProjectsObject[project]} handleClick={handleClick} index={index} />
内容的提问来源于stack exchange,提问作者sloont
相关产品推荐
相关产品推荐

