React中实现数组元素单独折叠:解决点击全展开/收起问题
解决单个学科项独立控制折叠/展开的问题
你遇到的问题核心在于所有学科共用了同一个display状态,所以点击任何一个都会触发所有项的展开/收起。要实现单独控制,我们需要给每个学科维护自己的展开状态,而不是用一个全局的状态值。
下面是具体的修改方案:
1. 调整状态结构
把原来单一的display状态改成一个对象,用来存储每个学科的展开状态,键可以用学科的id(保证唯一性),值用布尔值表示是否展开:
constructor(props){ super(props); this.handleClick = this.handleClick.bind(this); // 初始化状态:所有学科默认收起(可根据需求改成默认展开) this.state = { expandedItems: {} }; }
2. 修改点击事件处理函数
让handleClick接收学科的id,然后切换该id对应的展开状态:
handleClick(disciplineId) { this.setState(prevState => ({ expandedItems: { ...prevState.expandedItems, [disciplineId]: !prevState.expandedItems[disciplineId] } })); }
这里用了函数式更新setState,确保我们基于最新的状态进行修改,避免异步更新导致的逻辑错误。
3. 渲染时根据对应状态设置显示
在遍历学科的时候,根据当前学科id的状态来设置element的display样式:
render() { return ( <section className="l-section c-predictions" > <h2 className="header" >Predictions</h2> <div className="content"> {this.props.disciplines.map((discipline, index) => { // 判断当前学科是否展开,默认收起 const isExpanded = this.state.expandedItems[discipline.id] || false; return ( <div onClick={() => this.handleClick(discipline.id)} key={discipline.id} className="c-discipline"> <span className="name">{discipline.name}</span> - <span className="score">{disciplineScore(this.props.athlete.skillset, discipline.requirements)}</span> <div style={{ display: isExpanded ? 'block' : 'none' }} className="element"> <p>{discipline.tags !== undefined ? discipline.tags.toString().replace(',', ', ') : ''}</p> <p className="isIndividual">{discipline.isIndividual===true ? "Individual sport" : "Team sport"}</p> <img src={discipline.photo}/> </div> </div> ) })} </div> </section> ) }
另外建议把key改成discipline.id,因为name可能存在重复情况,id是更可靠的唯一标识。
这样修改后,每个学科的展开状态都是独立维护的,点击单个项只会切换自己的展开/收起状态,不会影响其他项啦。
内容的提问来源于stack exchange,提问作者Nat
相关产品推荐
相关产品推荐

