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
相关产品推荐
相关产品推荐

