返回

在React世界中探秘受控组件与非受控组件

前端

前言

在React应用中,表单元素(如input、textarea、select等)在内部会维护一个状态,而React本身的数据也由一个状态来维护。将这两者结合起来,React的状态就可以表示该组件的值的变量的值,并将其作为默认值传入表单内部。当表单内部有修改时,React的状态也会随之更新。这种双向绑定机制可以让我们轻松地更新表单中的值,但也可能导致代码的复杂性增加。

为了解决这个问题,React提供了受控组件和非受控组件的概念。受控组件将表单元素的状态完全由React来控制,而非受控组件则允许表单元素自行管理其状态。

受控组件

受控组件的本质是将表单元素的状态与React组件的状态进行绑定,当表单元素的值发生改变时,React组件的状态也会随之改变。这使得我们可以通过React组件来控制表单元素的输入值,实现双向数据绑定。

受控组件的实现方式非常简单,只需在表单元素上添加value属性,并将其值设置为React组件的状态即可。例如,以下代码演示了如何创建一个受控的输入框:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      value: ''
    };
  }

  handleChange = (event) => {
    this.setState({ value: event.target.value });
  };

  render() {
    return (
      <div>
        <input type="text" value={this.state.value} onChange={this.handleChange} />
      </div>
    );
  }
}

在上面的代码中,value属性的值是通过this.state.value来获取的,这意味着当组件的状态发生改变时,表单元素的值也会随之改变。

非受控组件

非受控组件与受控组件相反,它允许表单元素自行管理其状态,React组件不会对其进行任何控制。这意味着表单元素的值不会与React组件的状态绑定,因此我们无法通过React组件来更新表单元素的值。

非受控组件的实现方式也很简单,只需在表单元素上添加defaultValue属性,并将其值设置为表单元素的初始值即可。例如,以下代码演示了如何创建一个非受控的输入框:

class App extends React.Component {
  render() {
    return (
      <div>
        <input type="text" defaultValue="默认值" />
      </div>
    );
  }
}

在上面的代码中,defaultValue属性的值是"默认值",这意味着当表单元素首次加载时,其值将被设置为"默认值"。但是,当用户修改表单元素的值时,React组件并不会对该值进行任何更新。

受控组件与非受控组件的区别

受控组件和非受控组件的主要区别在于:

  • 数据流: 受控组件使用双向数据流,这意味着表单元素的值与React组件的状态绑定在一起,当表单元素的值发生改变时,React组件的状态也会随之改变。非受控组件使用单向数据流,这意味着表单元素的值不会与React组件的状态绑定在一起,React组件无法更新表单元素的值。
  • 代码复杂性: 受控组件的代码往往比非受控组件的代码更复杂,因为需要在组件中添加状态管理的逻辑。非受控组件的代码则比较简单,因为不需要添加状态管理的逻辑。
  • 性能: 受控组件的性能往往比非受控组件的性能更好,因为受控组件可以避免不必要的重新渲染。非受控组件的性能往往比受控组件的性能更差,因为非受控组件需要在每次表单元素的值发生改变时重新渲染。

何时使用受控组件和非受控组件

受控组件和非受控组件都有各自的优缺点,在不同的场景下使用不同的组件可以达到最佳的效果。

一般来说,当我们需要在表单元素中获取或更新数据时,应该使用受控组件。例如,当我们想要在表单元素中输入数据并将其存储在数据库中时,应该使用受控组件。

当我们需要在表单元素中显示数据但不需要更新数据时,可以使用非受控组件。例如,当我们想要在表单元素中显示用户的个人信息时,可以使用非受控组件。

结语

受控组件和非受控组件是React中两种重要的表单元素,它们都有各自的优缺点。在不同的场景下使用不同的组件可以达到最佳的效果。