React 中的受控组件与非受控组件
在 React 中,表单元素的处理可以分为受控组件和非受控组件两种方式。受控组件将表单数据交由 React 组件内部的 state 进行管理,而非受控组件则将表单数据储存在 DOM 元素中。下面我们来详细探讨这两种组件的特点和使用场景。
受控组件
受控组件的核心思想是将表单数据交由 React 组件内部的 state 进行管理。具体来说:
- 组件的 state 是表单的唯一数据源。
- 通过为表单元素绑定事件处理函数,在事件处理函数中更新 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 中获取表单数据。
受控组件的优点是:
- 数据流清晰,表单数据和 UI 始终保持一致。
- 方便对表单数据进行校验和处理。
但是,对于大型表单,受控组件可能会变得比较繁琐,因为每个表单元素都需要编写事件处理函数。
非受控组件
非受控组件将表单数据储存在 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 元素的引用,在表单提交时通过这些引用获取表单数据。
非受控组件的优点是:
- 代码相对简洁,不需要为每个表单元素编写事件处理函数。
- 适用于需要集成第三方 UI 库的情况。
但是,非受控组件也有一些缺点
- 表单数据和 UI 可能不同步,需要手动同步。
- 对表单数据的校验和处理相对麻烦。