You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中循环渲染列表时基于id控制单个元素下拉内容显隐的问题

问题根源

  1. 你定义的display是全局公用状态,所有循环生成的学生卡片都共用这一个开关,所以点击任意按钮都会触发所有卡片的显隐切换。你虽然存了被点击元素的唯一id到state,但完全没用来判断当前卡片要不要展示详情。
  2. 监听active变化的useEffect属于多余逻辑,完全不需要额外维护display状态,直接用当前遍历到的学生id和active.activeStudent做比对,就能判断当前卡片的显隐状态。

修复后完整代码

import React, { useState } from 'react';
import '../style/skeleton.css'
import '../style/style.css'

// 这里直接解构props拿到传递进来的student数组,写法更清晰
export default function Body({ student }) {
    // 只需要存当前激活的学生id即可,不需要额外的display状态
    const [active, setActive] = useState({
        activeStudent: null,
    });

    const handleClick = (id) => {
        // 点击逻辑:如果当前点击的是已经展开的学生,就收起,否则展开当前点击的学生
        setActive({
            activeStudent: active.activeStudent === id ? null : id
        })
    };


    return (
        <div>
            {student.map((data) => {
                // 核心判断:当前遍历的学生id是否等于激活的id,决定当前卡片的显隐
                const isCurrentActive = data.id === active.activeStudent;
                return (
                <div key={data.id} className="row border">
                    <div className="two-thirds column">
                        <h3>{data.firstName} {data.lastName}</h3>
                        <button onClick={() => handleClick(data.id)}>
                            {isCurrentActive ? '-' : '+'}
                        </button>
                        {isCurrentActive && (
                            <div>
                                <p>{data.addional} additonal data</p>
                            </div>
                        )}
                    </div>
                    
                </div>
                )
            })}
        </div>
        );
}

核心逻辑说明

  • 循环渲染的列表项做状态判断时,永远要和当前遍历项的唯一标识做比对,不要用全局布尔状态控制所有项的展示
  • 可以通过已有状态推导出来的内容,不要单独存额外状态,这里要不要展示详情完全可以通过激活id和当前项id的比对结果推导,不需要单独维护display状态
  • 非必要不要随便用useEffect监听状态再更新其他状态,简单的状态更新直接在事件回调里处理即可,避免出现多余的副作用逻辑漏洞

内容的提问来源于stack exchange,提问作者Jojo designs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 09:57:03