React通过数组渲染的单选按钮状态更新后UI未同步问题
问题根因
- 单选按钮组的
name属性配置不符合HTML规范:同一组需要互斥的单选按钮必须使用相同的name属性值,你当前代码中同一行的两个单选分别设置了name="html"和name="text",导致页面所有行的HTML单选归为同一组、TEXT单选归为另一组,多元素时选择会跨行冲突,这就是仅1个元素时功能正常的核心原因。 - 状态匹配逻辑和列表
key存在潜在问题:你用item.name作为状态更新的匹配条件,同时用index作为列表渲染的key,如果后续用户修改了输入框的名称、或者列表有增删排序操作,会出现状态匹配错误、视图更新异常的问题。
修复方案
- 给每个数组项添加唯一固定的
id字段,用于状态匹配和列表key - 同一行的两个单选按钮绑定相同的
name值,关联当前行的唯一标识,保证不同行的单选组互相独立 - 状态更新时用唯一
id匹配对应项,避免name修改导致匹配失效
修复后完整代码
import React, { useState } from 'react'; import './style.css'; export default function App() { const [subTemplate, setSubTemplate] = useState([ { id: 1, name: 'main', outputFormat: 'html' }, { id: 2, name: 'something else', outputFormat: 'text' } ]); const handleInputChange = (value, row, key) => { const updatedSubTemplate = subTemplate.map(item => { // 用唯一id匹配,不受name修改影响 if (item.id === row.id) { return { ...item, [key]: value }; } return item; }); setSubTemplate(updatedSubTemplate); }; const renderSubTemplates = () => { return subTemplate.map((item) => { return ( // 用唯一id当key,避免列表操作异常 <div key={item.id}> <input type="text" value={item.name} onChange={e => { handleInputChange(e.target.value, item, 'name'); }} /> <div> <input type="radio" name={`outputFormat_${item.id}`} checked={item.outputFormat === 'html'} onChange={e => { handleInputChange('html', item, 'outputFormat'); }} /> HTML </div> <div> <input type="radio" name={`outputFormat_${item.id}`} checked={item.outputFormat === 'text'} onChange={e => { handleInputChange('text', item, 'outputFormat'); }} /> TEXT </div> </div> ); }); }; return <div>{renderSubTemplates()}</div>; }
内容的提问来源于stack exchange,提问作者Erick
相关产品推荐
相关产品推荐

