单选按钮onChange触发非预期状态变更导致Card组件自动折叠问题
问题成因
- 核心问题是 DOM ID重复:你所有卡片下的单选按钮都设置了相同的
id="yes",而DOM规范要求id必须全局唯一,重复id会导致浏览器事件触发逻辑异常。点击其他卡片的单选按钮时,浏览器可能误识别为点击了第一个卡片内的同id元素,触发第一个卡片的onClick事件,把toggleValue设为第一个卡片的id,最终出现当前卡片折叠、第一张卡片展开的现象。 - 次要问题是 单选按钮分组配置错误:同组单选按钮需要设置相同的
name属性才能保证互斥选中,你当前没有给单选按钮加name属性,会导致所有卡片的单选按钮都属于同一个全局组,选中一个卡片的选项会自动取消其他卡片的选中状态。 - 潜在问题是 事件冒泡:单选按钮的点击事件会向上冒泡到父级
Card的onClick事件,即使没有id重复问题,后续如果修改Card点击逻辑为切换折叠状态,也会出现点单选同时触发折叠的异常。
修复方案
- 修正单选按钮的id、name属性,同时阻止事件冒泡到父级Card:
const [toggleValue, setToggleValue] = useState(null); // 给初始值避免隐式类型转换问题 // ... {Items.map((item) => ( <Card onClick={() => setToggleValue(item.id)} key={item.id}> <CardHeader text={item.text} /> {/* 可选:统一类型避免判断异常 */} <Collapse isOpen={String(toggleValue) === String(item.id)}> <CardBody> <FormGroup> <CustomInput value="1" type="radio" id={`vote_${item.id}_1`} // 保证id全局唯一 name={`vote_group_${item.id}`} // 同卡片单选归为一组 onChange={handleOptionChange(item.id, '1')} onClick={(e) => e.stopPropagation()} // 阻止冒泡到Card /> <CustomInput value="2" type="radio" id={`vote_${item.id}_2`} // 保证id全局唯一 name={`vote_group_${item.id}`} // 同卡片单选归为一组 onChange={handleOptionChange(item.id, '2')} onClick={(e) => e.stopPropagation()} // 阻止冒泡到Card /> </FormGroup> </CardBody> </Collapse> </Card> ))}
内容的提问来源于stack exchange,提问作者Dominic Abraham
相关产品推荐
相关产品推荐

