HOWTO · React
在 React 中使用 onChange 事件
onChange 是 React 中最常见的输入事件之一。本文将帮助你了解它的工作原理。
本页内容
React 的 onChange 属性可让组件响应表单控件的变化。事件处理函数读取发生变化的控件值,并更新用于显示该值的状态。React 的 onChange 并不等同于原生 HTML 的 onchange 属性:React 通过自己的事件系统处理表单变化,其行为适用于 React 控件。
当组件需要管理当前表单值、验证该值,或在界面其他位置使用它时,可以使用受控输入。基本做法是将状态值传给控件,并在其 onChange 处理函数中更新状态。
理解 onChange 事件
使用 JSX 属性 onChange,即可为 input、textarea 或 select 添加事件处理函数。对于文本框和选择框,读取 event.target.value;对于复选框,读取布尔值 event.target.checked。随后,处理函数会更新与该控件关联的状态。
在受控表单控件中,显示的值来自状态。处理函数更新状态后,React 会用新值重新渲染控件,使界面与组件数据保持同步。如果组件在交互过程中无需管理控件值,可以选择非受控控件。
使用 onChange 处理文本输入
对于文本输入框,应将字符串保存在状态中,通过 value 传给控件,并根据事件更新状态。假设类组件的状态中包含 name,可以这样编写 JSX 控件:<input value={this.state.name} onChange={event => this.setState({ name: event.target.value })} />。状态更新后,显示的文本会随每次编辑而变化。输入框在整个使用期间都应保持字符串类型的状态值。
下面的可运行 JavaScript 单独演示文本框、复选框和选择框的处理函数逻辑。它通过简单的状态设置函数展示各处理函数读取的事件属性,并不会渲染 React 控件。本文中的 JSX 则展示如何将这些值连接到 React 受控控件。输出块中的可见标签保持英文;它们展示的是示例记录的事件值。
let name = '';
let subscribed = false;
let category = 'books';
const setName = (value) => { name = value; };
const setSubscribed = (value) => { subscribed = value; };
const setCategory = (value) => { category = value; };
const handleNameChange = (event) => setName(event.target.value);
const handleSubscribedChange = (event) => setSubscribed(event.target.checked);
const handleCategoryChange = (event) => setCategory(event.target.value);
handleNameChange({ target: { value: 'Ada' } });
handleSubscribedChange({ target: { checked: true } });
handleCategoryChange({ target: { value: 'music' } });
console.log(`Name: ${name}`);
console.log(`Subscribed: ${subscribed}`);
console.log(`Category: ${category}`);
Name: Ada
Subscribed: true
Category: music
在 React 组件中,这个可运行示例里的设置函数对应状态更新。控件显示的值来自该状态,因此 React 可以让视图与数据保持同步。
使用复选框
复选框表示一个布尔选择,因此应通过 checked 控制其选中状态,并在处理函数中读取 event.target.checked。在类组件中,可以这样设置复选框:checked={this.state.subscribed} 和 onChange={event => this.setState({ subscribed: event.target.checked })}。复选框的 value 是提交表单时使用的值,并不表示用户是否选中了它。
使用 onChange 处理下拉选择框
对于选择控件,应通过 value 传入当前选中状态,并从 event.target.value 读取新选项。例如,可以使用 <select value={this.state.category} onChange={event => this.setState({ category: event.target.value })}><option value="books">Books</option><option value="music">Music</option></select>。选项的值会存入状态,可能与用户看到的标签不同。更新状态后,选中项及依赖该选项的界面都会以同一数据源为准。
使用 onChange 的最佳实践
让处理函数专注于读取事件并更新相关状态。根据表单的实际需求安排验证方式:例如,为了即时反馈,可以在用户输入时验证;如果输入过程中提供反馈会造成干扰,则可以在提交时验证。确保 value 属性与对应状态使用一致的类型,并使用 checked 管理复选框状态。
当处理函数会启动耗时操作时,例如筛选大型数据集或发送搜索请求,防抖可能有所帮助。防抖会延迟响应,也不会自动阻止 React 渲染,因此只有在工作负载和用户体验都适合时才使用。每次按键都更新受控状态是常见做法。
通过程序直接更改输入控件的 DOM 值属于进阶场景。直接赋值本身并不能保证 React 会观察到变化或调用预期的处理函数。优先更新控制该输入框的状态。如果外部代码必须与表单控件交互,尽可能使用组件的公开接口,并在该集成场景中验证行为;setNativeValue 之类的辅助函数名称并不代表通用的 React API,也不是有保证的修复方法。
总结
React 的 onChange 处理函数将用户编辑与组件状态连接起来。文本和选择控件读取 value,复选框读取 checked,然后根据更新后的状态渲染受控控件。应根据表单需求决定如何验证以及是否使用防抖,不要将它们当作一概适用的规则。
常见问题
-
React 中的
onChange有什么作用? 表单控件发生变化时,它会调用处理函数,让组件读取新值并更新数据或状态。 -
如何处理文本输入框? 将字符串状态值传给输入框的
value属性,并在onChange中根据event.target.value更新该状态。 -
如何处理复选框? 通过
checked属性使用布尔状态控制复选框,并根据event.target.checked更新该状态。 -
如何处理 select 元素? 将状态设置为它的
value,并在选项变化时根据event.target.value更新该状态。 -
每个
onChange处理函数都应该使用防抖吗? 不应该。只有当处理函数会启动耗时操作时,才考虑使用防抖;每次状态更新都不需要防抖,而且防抖也不能保证减少渲染次数。 -
为什么通过程序更改值可能不会调用我的处理函数? 直接给 DOM 值赋值不一定会触发 React 的变化处理。请更新控制输入框的状态,或使用组件支持的接口。