跳到主要内容

React 中的受控组件与非受控组件

在 React 中,表单元素的处理可以分为受控组件和非受控组件两种方式。受控组件将表单数据交由 React 组件内部的 state 进行管理,而非受控组件则将表单数据储存在 DOM 元素中。下面我们来详细探讨这两种组件的特点和使用场景。

受控组件

受控组件的核心思想是将表单数据交由 React 组件内部的 state 进行管理。具体来说:

  1. 组件的 state 是表单的唯一数据源。
  2. 通过为表单元素绑定事件处理函数,在事件处理函数中更新 state,从而控制表单元素的值。

下面是一个简单的受控组件示例

class ControlledForm extends React.Component {
state = {
username: '',
password: '',
};

handleChange = (event) => {
const { name, value } = event.target;
this.setState({ [name]: value });
};

handleSubmit = (event) => {
event.preventDefault();
console.log(this.state);
};

render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" name="username" value={this.state.username} onChange={this.handleChange} />
<input type="password" name="password" value={this.state.password} onChange={this.handleChange} />
<button type="submit">Submit</button>
</form>
);
}
}

在这个示例中,表单元素的值都由组件的 state 控制。当用户输入时,触发onChange事件,在事件处理函数中更新 state,进而更新表单元素的值。当表单提交时,可以直接从 state 中获取表单数据。

受控组件的优点是:

  1. 数据流清晰,表单数据和 UI 始终保持一致。
  2. 方便对表单数据进行校验和处理。

但是,对于大型表单,受控组件可能会变得比较繁琐,因为每个表单元素都需要编写事件处理函数。

非受控组件

非受控组件将表单数据储存在 DOM 元素中,而不是组件的 state 中。在提交表单时,通过 DOM API 获取表单数据。

下面是一个简单的非受控组件示例

class UncontrolledForm extends React.Component {
handleSubmit = (event) => {
event.preventDefault();
const username = this.usernameInput.value;
const password = this.passwordInput.value;
console.log({ username, password });
};

render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" ref={(input) => (this.usernameInput = input)} />
<input type="password" ref={(input) => (this.passwordInput = input)} />
<button type="submit">Submit</button>
</form>
);
}
}

在这个示例中,我们使用ref属性获取 DOM 元素的引用,在表单提交时通过这些引用获取表单数据。

非受控组件的优点是:

  1. 代码相对简洁,不需要为每个表单元素编写事件处理函数。
  2. 适用于需要集成第三方 UI 库的情况。

但是,非受控组件也有一些缺点

  1. 表单数据和 UI 可能不同步,需要手动同步。
  2. 对表单数据的校验和处理相对麻烦。