React条件渲染切换时输入框内容重叠复用问题求解
问题成因
这个问题是React虚拟DOM Diff算法的节点复用逻辑和非受控组件的特性共同导致的:
- 你当前两个渲染分支的根节点都是无属性的React Fragment(
<>...</>),内部第一个元素都是label+input的组合。React做节点比对时,默认会按同层级节点的顺序进行匹配复用,不会优先参考id等自定义属性判断节点是否需要替换。 - 你使用的input属于非受控组件,没有绑定
value属性关联React状态,输入的内容是直接存储在真实DOM节点上的。当React复用了前一个分支的input DOM节点时,节点上存储的输入内容就会被带到新渲染的输入框中。
另外你的代码存在两处不影响本次问题但需要修正的语法错误:
handleSwitch函数中调用的setstate应该是你声明的状态更新函数setSwitch- Switch组件的
onClick事件绑定写法错误,当前() => handleSwitch只返回了函数没有执行,应该改为onClick={handleSwitch}或者onClick={() => handleSwitch()}
解决方案
可以任选以下一种方式修复:
- 给两个渲染分支的根节点添加唯一的
key属性,明确告知React这两个结构是完全不同的,不需要复用节点:{!switchButton ? <React.Fragment key="single"> <label htmlFor="input_1">Input 1</label> <input id="input_1"/> </React.Fragment> : <React.Fragment key="double"> <label htmlFor="input_2">Input 2</label> <input id="input_2" /> <label htmlFor="input_3">Input 3</label> <input id="input_3" /> </React.Fragment> } - 将所有input改为受控组件,给每个input绑定对应的
value和onChange属性关联React状态,即使节点被复用,状态也会覆盖DOM上的原有内容。 - 给每个input添加唯一的
key属性,避免React按顺序匹配复用input节点。
内容的提问来源于stack exchange,提问作者rgarcia97
相关产品推荐
相关产品推荐

