因Key重复导致多Dropdown同步选中值的问题排查与解决
问题原因与解决方案
核心问题
你遇到的同步选中问题,根源是所有下拉框绑定了同一个表单字段名:所有Controller的name都用了固定的typeCd,导致它们指向表单的同一个属性,选中值自然会同步。另外,直接修改共享的IdTypes对象也存在引用共享的潜在问题,组件key的使用也可以优化。
解决步骤
1. 给每个下拉框分配唯一的表单字段名
结合每行的唯一标识(比如seq)生成独立的字段名,让每个下拉框绑定不同的表单值。
2. 避免修改共享的字段对象
不要直接修改IdTypes里的原对象,每次循环时创建新的字段对象,防止多个下拉框共享同一个options数组引用。
3. 优化组件key的使用
用每行的seq(而非index)作为外层Grid和Grid Item的key,避免row顺序变化时key重复导致的渲染异常;同时下拉框的MenuItem用选项的唯一值(比如cd)作为key,替代不稳定的index。
修改后的代码示例
const IdTypes = [ { label: 'Identifications Type', key: 'typeCd', options: [] as string[], type: 'select', }, ]; const rows = ['0001', '0002']; // 渲染行部分 {rows.map((seq) => ( <Grid container spacing={1} key={seq}> {IdTypes.map((baseField) => { // 创建新的字段对象,避免修改原IdTypes const field = { ...baseField, options: getDropdownData(jsonData, 'typeCd').map(item => `${item.cd} - ${item.desc}`) }; return ( <Grid item key={`${baseField.key}_${seq}`}> {renderField(field, seq)} </Grid> ); })} </Grid> ))} // 渲染字段函数 const renderField = (field: any, seq: string) => { const { label, type, key, options } = field; if (type === 'select') { // 生成唯一表单字段名 const uniqueFieldName = `${key}_${seq}`; // 若需要批量处理表单数据,也可以用数组格式:`${key}[${seq}]` return ( <Controller name={uniqueFieldName} control={control} render={({ field }) => ( <FormControl size='small' fullWidth> <InputLabel>{label}</InputLabel> <Select {...field} label={label}> {(options || []).map((option: string) => { const value = option.split('-')[0].trim(); return ( <MenuItem key={value} value={value}> {option} </MenuItem> ); })} </Select> </FormControl> )} /> ); } };
说明
- 唯一字段名保证了每个下拉框绑定独立的表单值,彻底解决同步选中问题;
- 新创建的字段对象避免了多个组件共享同一个
options引用的潜在bug; - 更稳定的key值提升了组件渲染的性能和可靠性。
内容的提问来源于stack exchange,提问作者Karan
相关产品推荐
相关产品推荐

