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

React数组生成表单输入框:解决联动与清空问题

循环生成的同义词输入框独立控制与清空解决方案

我在表单中通过map循环生成输入框,每个列表项包含标题、值及同义词输入区域,代码如下:

{itemsList.map((item, i) => (                  
  <>                
    <div className="row align-items-center" key={i}>    
      <div className="row mt-3">
        <div className="col-md-2">
          <label htmlFor="link_title" className="form-label text-center mt-1" >
            <h5> {i + 1}- Valor de la Lista: </h5>
          </label>
        </div>         
        <div className='col-md-4'>                        
          <input
            className='form-control'
            onChange={handleChange}
            id={i}
            name='title_item'
            value={'' || item.title_item}
            type="text"
            required
            onKeyDown={(e) => { e.key === 'Enter' && e.preventDefault(); }}    
          />                    
        </div>
        <div className="col-md-1">
          <label htmlFor="link_title" className="form-label text-center mt-1" >
            <h5> Valor: </h5>
          </label>
        </div> 
        <div className='col-md-4'>
          <input
            className='form-control'
            onChange={handleChange}
            id={i}
            name='value'
            value={'' || item.value}
            type="text"
            required
            onKeyDown={(e) => { e.key === 'Enter' && e.preventDefault(); }}    
          />   
           
        </div> 
      </div>
    </div>
      <div className='col-md-1 '>
        <label htmlFor="link_title" className="form-label mt-1" >
          <h5> Sinonimos: </h5>
        </label>
      </div>
    
        <ul className='col-md-5 ms-auto '>
        {sinoms.map((sinom, i) => (
           item.sinonimos.includes(sinom)  ?
          <>                            
            <li key={i}>
              <div>
                {sinom}{''}                                 
                <i className="bi bi-x-circle ms-3" 
                 style={{color: 'red'}} type='button'  
                  onClick={() => {                                    
                    deleteSinom(sinom);
                  }}>
                </i>                                 
              </div>
            </li> 
          </>                             
        : null
        ))
        } 
        <input className="col-md-3 me-2 mt-3"                                
              key={item.idResponse}
              value={nuevosin}
              //name={nuevosin} //works but not clean when click button
              id={item.idResponse}
              onChange={e => 
       (setNuevosin(e.target.value.trimRight(), 
         e.target.name))}
              onKeyDown={(e) => { e.key === 'Enter' && 
           e.preventDefault(); }}    
            />
            <button className="btn btn-outline-primary 
          col-md-4 " type='button' onClick={() => ( 
       handleClick(item.idResponse))}>
              Inserta un Nuevo Sinonimo
            </button>
    </ul>
  </>
))}

当前遇到两个问题:

  • 使用value={nuevosin}时,所有同义词输入框会同步显示相同内容
  • 使用name={nuevosin}时输入正常,但点击添加同义词按钮后输入框无法清空

需要实现:单个输入框独立输入,且点击添加按钮后自动清空对应输入框。


解决方案

核心思路是为每个列表项的同义词输入框维护独立的状态,不再使用全局的单个状态变量。

1. 修改状态结构

将原来的单个nuevosin状态改为对象,用每个item的idResponse作为键,存储对应输入框的值:

import { useState } from 'react';

// 初始化空对象,后续动态添加键值对
const [nuevosinMap, setNuevosinMap] = useState({});

2. 更新输入框的value与onChange逻辑

修改同义词输入框的属性,绑定到对应item的独立状态:

<input 
  className="col-md-3 me-2 mt-3"                                
  key={item.idResponse}
  value={nuevosinMap[item.idResponse] || ''} // 取当前item对应的输入值,默认空字符串
  id={item.idResponse}
  onChange={(e) => {
    const inputValue = e.target.value.trimRight();
    // 更新状态,仅修改当前item对应的键值
    setNuevosinMap(prevState => ({
      ...prevState,
      [item.idResponse]: inputValue
    }));
  }}
  onKeyDown={(e) => { e.key === 'Enter' && e.preventDefault(); }}    
/>

3. 修改添加按钮的点击事件

在handleClick函数中,完成添加同义词后,清空当前输入框对应的状态:

const handleClick = (itemId) => {
  // 获取当前输入框的内容
  const newSynonym = nuevosinMap[itemId];
  if (!newSynonym) return; // 空值不执行添加操作

  // 执行添加同义词的业务逻辑(示例:更新itemsList中的对应item)
  setItemsList(prevList => prevList.map(item => {
    if (item.idResponse === itemId) {
      return {
        ...item,
        sinonimos: [...item.sinonimos, newSynonym]
      };
    }
    return item;
  }));

  // 清空当前输入框的状态
  setNuevosinMap(prevState => ({
    ...prevState,
    [itemId]: ''
  }));
};

4. 清理冗余代码

删除原来的nuevosin和setNuevosin变量,不再使用。


额外优化建议

  • sinoms.map中的key建议使用sinom(如果同义词唯一)或${item.idResponse}-${sinom},避免与外层循环的i冲突,提升React渲染性能
  • 输入框的name属性可设置为sinom_${item.idResponse},方便后续表单提交时区分不同item的同义词输入内容

内容的提问来源于stack exchange,提问作者ddaudiosolutions

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:21:13