React如何按元素ID调用函数,避免点击单个元素触发全部显示
解决React列表点击单个元素仅展开对应子分类的问题
问题核心是你用了单个布尔值状态showsubcat控制所有子分类的显示,所有列表项共享同一个状态,自然会出现点击任意元素全展开/收起的情况。要实现单个元素独立控制,需要记录当前展开的元素ID而非统一的布尔值。
修改方案:
- 更新状态定义:把布尔状态改成记录当前展开的分类ID,初始值设为
null(表示没有展开的分类)
const [openCategoryId, setOpenCategoryId] = useState(null);
- 修改点击事件处理函数:点击时传入当前分类的ID,判断如果当前ID已经是展开状态就关闭,否则切换到该ID
const toggleSubCategory = (id) => { setOpenCategoryId(prevId => prevId === id ? null : id); };
- 调整JSX逻辑:只有当当前分类的ID和
openCategoryId匹配时,才渲染子分类;同时注意React中要用className替代class,并且map循环要加唯一key
{data.map((item) => { return ( <React.Fragment key={item.id}> <li className="list-group-item" onClick={() => toggleSubCategory(item.id)}> {item.main_category} </li> {openCategoryId === item.id && ( <li> <i className="las la-angle-right"></i> {item.sub_category} </li> )} </React.Fragment> ); })}
额外说明:
- 避免重复ID:原代码中
id="sub_category"会在循环中重复,建议去掉或者改成动态ID(比如id={sub-category-${item.id}}) - 函数定义用
const替代let,符合React组件内的最佳实践 - 如果需要支持同时展开多个子分类,可以把状态改成数组,点击时添加/移除对应ID:
const [openCategoryIds, setOpenCategoryIds] = useState([]); const toggleSubCategory = (id) => { setOpenCategoryIds(prevIds => prevIds.includes(id) ? prevIds.filter(itemId => itemId !== id) : [...prevIds, id] ); }; // JSX判断改成: {openCategoryIds.includes(item.id) && (...)}
内容的提问来源于stack exchange,提问作者boyenec
相关产品推荐
相关产品推荐

