React中使用immutability helper实现选中值后动态新增文本字段
实现方案
1. 统一字段结构
首先把values数组每一项的结构统一,方便后续逻辑复用:
// 统一后的字段结构 interface ValueItem { fieldName: string; // 字段名,比如firstName、userId id: string; // 唯一标识 valueType: 'string' | 'number' | 'boolean'; // 字段类型 placeHolder?: string; value?: any; } // 初始化示例 const initialValues: ValueItem[] = [ { fieldName: 'firstName', id: 'text', valueType: 'string', placeHolder: '请输入姓名' }, { fieldName: 'userId', id: 'number', valueType: 'number', placeHolder: '请输入用户ID' } ];
2. 定义类型映射表(替代if-else判断)
提前把所有类型对应的配置项写在映射表里,后续加新类型只需要改这个表,不用动业务逻辑:
const TYPE_CONFIG = { string: { component: 'input', // 对应渲染的组件 defaultPlaceholder: '请输入文本内容', defaultValue: '' }, number: { component: 'inputNumber', defaultPlaceholder: '请输入数字', defaultValue: 0 }, boolean: { component: 'switch', defaultPlaceholder: '请选择开关状态', defaultValue: false } } as const;
3. 优化更新方法
把两个更新方法合并,选类型的时候自动同步占位符等配置,不需要单独调用两次更新:
const setValueType = (type: keyof typeof TYPE_CONFIG, index: number) => { if (index < 0 || index >= data.values.length) return; const config = TYPE_CONFIG[type]; setValueData(update(data, { values: { [index]: { valueType: { $set: type }, placeHolder: { $set: config.defaultPlaceholder }, value: { $set: config.defaultValue } } } })); };
4. 实现新增选项方法
下拉框新增选项时直接初始化默认结构即可:
const addNewOption = (fieldName: string, id: string) => { setValueData(update(data, { values: { $push: [ { fieldName, id, // 默认给string类型,也可以根据新增的选项预设类型 valueType: 'string', placeHolder: TYPE_CONFIG.string.defaultPlaceholder, value: TYPE_CONFIG.string.defaultValue } ] } })) }
5. 条件渲染输入组件
渲染的时候直接根据当前项的valueType从映射表取对应组件渲染即可:
{ data.values.map((item, index) => ( <div key={item.id}> <label>{item.fieldName}</label> {/* 按类型渲染对应组件 */} {item.valueType === 'string' && ( <input type="text" placeholder={item.placeHolder} value={item.value} onChange={(e) => handleValueChange(e.target.value, index)} /> )} {item.valueType === 'number' && ( <input type="number" placeholder={item.placeHolder} value={item.value} onChange={(e) => handleValueChange(Number(e.target.value), index)} /> )} {item.valueType === 'boolean' && ( <input type="checkbox" checked={item.value} onChange={(e) => handleValueChange(e.target.checked, index)} /> )} {/* 下拉框切换类型 */} <select value={item.valueType} onChange={(e) => setValueType(e.target.value as keyof typeof TYPE_CONFIG, index)} > <option value="string">文本</option> <option value="number">数字</option> <option value="boolean">布尔值</option> </select> </div> )) }
内容的提问来源于stack exchange,提问作者Rak1994
相关产品推荐
相关产品推荐

