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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:15:09