React中onClick事件在一个div生效另一个不生效,如何仅展开对应折叠列表?
问题核心原因
- 你当前使用单个全局布尔值
collapsible控制所有列表项的展开状态,所有项共用同一个状态触发条件,自然会出现点击一个全部展开的问题 - 你将点击事件绑定到了需要折叠展示的内层
div上,初始状态下该div内部没有渲染实际内容,高度为0无法被点击,所以事件不会触发 - 你直接给
onClick绑定this.showCollapsible()会在render阶段直接执行方法触发setState,render过程中更新状态会触发重渲染进入逻辑循环,因此会抛出对应警告
解决步骤
1. 调整state结构
把原本存储单个布尔值的状态,改为存储当前展开项的唯一标识(此处用唯一的imageName作为标识即可):
state = { // 其他现有state collapsedKey: null // 初始为null表示没有展开项 }
2. 修改折叠控制方法
给方法添加参数接收要展开的项标识,关闭方法直接重置标识为null即可:
// 展开方法,接收当前点击项的imageName作为参数 showCollapsible = (imageName) => { this.setState({ collapsedKey: imageName }) } // 关闭方法 hideCollapsible = () => { this.setState({ collapsedKey: null }) }
3. 调整render逻辑
- 将点击事件绑定到外层可点击的信息展示层,用箭头函数包裹方法调用传入当前项的标识,避免render阶段直接执行
- 仅当当前项的
imageName与state中存储的collapsedKey相等时,才渲染该条目的列表内容
render() { return ( this.state.data.map(item => { return ( <div id={'imageTableItemComponent'} key={item.imageName} {/* 把点击事件绑到外层可点击区域,用箭头函数传参 */} onClick={() => this.showCollapsible(item.imageName)} > {item.imageName} - {item.tags.length} <div id={'collapsibleTagList'} key={item.tags}> {/* 仅当前项匹配展开标识时渲染内容 */} {this.state.collapsedKey === item.imageName && <TagTableComponent data={item} onClose={this.hideCollapsible}/>} </div> </div> ) }) ) }
额外说明
如果需要支持同时展开多个项,可以把state的collapsedKey改为Set结构,点击时判断是否存在该标识,存在则删除、不存在则添加,渲染时判断Set中是否包含当前项的标识即可。
内容的提问来源于stack exchange,提问作者TraktorJack
相关产品推荐
相关产品推荐

