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

为何React非受控输入元素在Reconciliation时丢失输入内容?

非受控输入框在切换包裹元素后丢失内容的原因
export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0,
      wrapContent: false
    }
  }

  handleAdd = () => {
    this.setState({ counter: this.state.counter + 1 });
  }

  toggleWrap = () => {
    this.setState(state => state.wrapContent = !state.wrapContent);
  }

  wrapContent(content) {
    return this.state.wrapContent ?
      <div className="bg-secondary p-2">
        <div className="bg-light">{content}</div>
      </div>
      : content;
  }

  render() {
    return this.wrapContent(
      <React.Fragment>
        <input type="checkbox" checked={this.state.wrapContent} onChange={this.toggleWrap} />
        <input className="form-control"/>  {/* <--------value disappear after toggling */}
        <DisplayCounter counter={this.state.counter} />
        <div className="text-center">
          <button className="btn btn-primary" onClick={this.handleAdd}>Increment</button>
        </div>
      </React.Fragment>
    );
  }
}

class DisplayCounter extends Component {
  render() {
    return <React.Fragment><div>
      <h2>{this.props.counter}</h2>
    </div></React.Fragment>
  }
}

你遇到的现象是:在输入框中输入文本,点击递增按钮后切换复选框,输入框的值消失,但DisplayCounter的数值仍保留。核心疑惑是:React的Virtual DOM明明能最小化更新,为什么对非受控输入元素无效?

根本原因

这和React的DOM diff算法逻辑直接相关:

  • 非受控输入的DOM被销毁重建:你的wrapContent函数在切换状态时,会把原本直接返回的内容(包含input),改为嵌套在两层<div>中。React在对比前后两次渲染的DOM结构时,会发现input元素的父级层级完全改变——之前是直接在React.Fragment下,现在变成了内层<div>的子元素。此时React会判定这是一个全新的DOM元素,直接销毁原来的input(里面存储着用户输入的内容),重新创建一个默认值为空的新input,导致输入内容丢失。
  • 自定义组件不受影响:DisplayCounter是自定义React组件,React在diff时会优先对比组件类型。只要组件类型一致(都是DisplayCounter),React就会复用已有的组件实例,不会卸载重建。它的数值来自父组件传递的counter props,始终由父state维护,所以切换包裹结构时,组件实例保留,props正常更新,数值自然不会丢失。

补充说明

非受控输入的内容只存储在DOM节点本身,没有和React的state绑定,一旦DOM节点被销毁,里面的内容就会丢失。而受控输入的内容由state维护,即使DOM重建,也会从state中读取值渲染,不会丢失。另外,也可以给input添加一个固定的key属性,让React识别这是同一个元素,即使父级结构变化,也会复用该DOM节点,从而保留输入内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:12:59