React表单输入每输1个字符就失焦?传递props时遇此问题
问题解决方法
核心问题分析
- 输入框失焦:条件渲染时使用无唯一标识的
Fragment,父组件状态更新触发重渲染后,React无法识别组件实例,会卸载并重建<ItemsEdit/>,导致输入框失去焦点。 - 共享输入内容:单一的
updateName状态被所有编辑项共用,输入时会同步到所有编辑组件中。
具体修复步骤
1. 重构状态,实现独立输入值存储
将单一的updateName改为按item id存储的对象,确保每个编辑项的输入值独立:
// 父组件状态修改 const [showItem, setShowItem] = useState({}) // 用对象存储每个item的更新名称,key为item的id const [updateNames, setUpdateNames] = useState({})
2. 给条件渲染的Fragment添加唯一Key
确保React能识别组件身份,避免重渲染时卸载重建:
{nfts.map((nft,i) => { return( <div className="items" key={nft.id} > {showItem.id == nft.id ? {/* 给编辑状态的Fragment加唯一key */} <React.Fragment key={`edit-${nft.id}`}> <form onSubmit={handleSubmit}> <ItemsEdit items={showItem} // 传入当前item对应的输入值,默认显示原名称 updateName={updateNames[showItem.id] || showItem.name} // 传入针对当前item的状态更新方法 setUpdateName={(value) => setUpdateNames(prev => ({ ...prev, [showItem.id]: value }))} // 把关闭编辑的方法传给子组件 setShowItem={setShowItem} /> </form> </React.Fragment> : {/* 给查看状态的Fragment加唯一key */} <React.Fragment key={`view-${nft.id}`}> <Items items={nft}></Items> </React.Fragment> } </div> ) })}
3. 修正子组件的按钮类型与状态调用
避免返回按钮触发表单提交,同时确保能正确调用父组件的状态方法:
const ItemsEdit = ({items, setUpdateName, updateName, setShowItem}) => { return ( <> <input id='name' type="text" value={updateName} placeholder="NFT name" onChange={e => setUpdateName(e.target.value)} /> <p>{items.id}</p> <img src={items.data.img} alt="" /> <div className="buttons"> <button type='submit'> Update </button> {/* 将按钮类型改为button,避免触发表单提交 */} <button type='button' className='left' onClick={() => setShowItem({})} > <ion-icon name="arrow-back-circle-outline"></ion-icon> </button> </div> </> ) }
内容的提问来源于stack exchange,提问作者Myth Vince
相关产品推荐
相关产品推荐

