React开发中列表点击函数仅作用于首个列表项的问题求助
问题根因
- 你调用
document.getElementsByClassName获取元素时,默认取匹配到的第一个元素,所以无论点击哪个列表项的按钮,操作的永远是第一个列表的隐藏块和箭头,和你实际点击的元素无关。 - React框架设计理念是状态驱动视图,直接操作原生DOM不符合开发规范,容易出现状态和视图不同步的问题。
- 你的CSS代码存在笔误:
.hidden-items前面多写了一个.,会导致隐藏样式不生效。
修复方案
改用React状态控制显隐逻辑,不需要操作原生DOM,修改后的代码如下:
JS代码
// 别忘了引入useState import { useState } from 'react'; import { FaAngleDown } from 'react-icons/fa'; const CardConference = ({ content }) => { // 存储当前展开的城市索引,值为null时代表没有展开的项 const [activeCityIndex, setActiveCityIndex] = useState(null); const toggleItems = (index) => { // 如果点击的是已经展开的项则收起,否则展开当前点击项 setActiveCityIndex(activeCityIndex === index ? null : index); } return ( <div className="card card-conferences "> <h4> {content[0].title} </h4> <ul> {content[0].cities.map((city, index) => ( // React循环渲染必须加唯一key,有业务id优先用业务id代替index <div key={index}> <li className="city-name"> {city.name} <button className="btn button-arrow" onClick={() => toggleItems(index)} > <FaAngleDown color="#717171" className={`arrow-down ${activeCityIndex === index ? 'rotate-arrow' : ''}`} /> </button> </li> <ul className={`hidden-items ${activeCityIndex === index ? 'show-items' : ''}`}> {city.conferenties.map((conf, confIndex) => ( <li key={confIndex} className="hidden-item">{conf} </li> ))} </ul> </div> ))} </ul> </div > ); } export default CardConference;
CSS代码
.arrow-down { position: absolute; margin-top: -11px; margin-left: -6px; transition: transform 1s; } .rotate-arrow { transform: rotate(180deg); } /* 修正多余的.符号 */ .hidden-items { display: none; } /* 新增展开状态样式 */ .hidden-items.show-items { display: block; }
扩展说明
如果需要支持多个列表项同时展开,只需把状态改成数组类型存储所有展开的索引,切换时往数组中添加/删除对应索引即可。
内容的提问来源于stack exchange,提问作者bosman2
相关产品推荐
相关产品推荐

