React切换输入表单集时旧输入值残留问题问询
表单切换时输入值残留的原因及解决方案
问题原因
这是React的DOM复用机制导致的。React为了提升渲染性能,会尽可能复用结构相似的DOM元素。当你从模式A切换到模式B时,前一组的input元素会被后一组的input复用——比如模式A的第一个input会被模式B的第一个input复用,模式A的第二个input会被模式B的第二个input复用,所以之前输入的值会保留在被复用的输入框里。
解决方案
方案一:给输入框添加唯一key属性
给每组的每个input设置独一无二的key,让React能区分不同的输入框,避免复用旧DOM。修改后的代码如下:
import React, { useState } from "react"; export default function App() { const [mode, setMode] = useState("a"); const handleModeChange = (e) => { const checked = e.target.checked; setMode(checked ? "b" : "a"); }; return ( <div className="App"> <div> <input type="checkbox" onChange={handleModeChange} /> {mode === "a" ? ( <div> <label>Item A:</label> <input key="mode-a-item1" /> <br /> <label>Item B:</label> <input key="mode-a-item2" /> </div> ) : ( <div> <label>Item Z:</label> <input key="mode-b-item1" /> <br /> <label>Item X:</label> <input key="mode-b-item2" /> <br /> <label>Item Y:</label> <input key="mode-b-item3" /> <br /> </div> )} </div> </div> ); }
方案二:使用受控组件管理输入状态
如果需要保留每组表单的输入值(切换回来时能看到之前输入的内容),可以为每组表单单独维护状态,切换模式时渲染对应状态的输入框:
import React, { useState } from "react"; export default function App() { const [mode, setMode] = useState("a"); const [modeAValues, setModeAValues] = useState({ itemA: "", itemB: "" }); const [modeBValues, setModeBValues] = useState({ itemZ: "", itemX: "", itemY: "" }); const handleModeChange = (e) => { const checked = e.target.checked; setMode(checked ? "b" : "a"); }; const handleAInputChange = (e) => { const { name, value } = e.target; setModeAValues(prev => ({ ...prev, [name]: value })); }; const handleBInputChange = (e) => { const { name, value } = e.target; setModeBValues(prev => ({ ...prev, [name]: value })); }; return ( <div className="App"> <div> <input type="checkbox" onChange={handleModeChange} /> {mode === "a" ? ( <div> <label>Item A:</label> <input name="itemA" value={modeAValues.itemA} onChange={handleAInputChange} /> <br /> <label>Item B:</label> <input name="itemB" value={modeAValues.itemB} onChange={handleAInputChange} /> </div> ) : ( <div> <label>Item Z:</label> <input name="itemZ" value={modeBValues.itemZ} onChange={handleBInputChange} /> <br /> <label>Item X:</label> <input name="itemX" value={modeBValues.itemX} onChange={handleBInputChange} /> <br /> <label>Item Y:</label> <input name="itemY" value={modeBValues.itemY} onChange={handleBInputChange} /> <br /> </div> )} </div> </div> ); }
内容的提问来源于stack exchange,提问作者Wellwoah
相关产品推荐
相关产品推荐

