在 React 中,onChange 和 onInput 有什么区别?

IT技术 javascript reactjs dom-events
2021-03-28 03:07:11

我试过四处寻找答案,但大多数都在 React 的上下文之外,onChange在模糊时触发。

在执行各种测试时,我似乎无法分辨这两个事件有何不同(当应用于 textarea 时)。任何人都可以对此有所了解吗?

6个回答

似乎没有真正的区别

出于某种原因,React 为Component.onChangeDOMelement.oninput事件附加了侦听器请参阅表单文档中的注释:

React 文档 - 表单

有更多人对这种行为感到惊讶。有关更多详细信息,请参阅 React 问题跟踪器上的此问题:

记录 React 的 onChange 如何与 onInput 相关 #3964

引用关于该问题的评论:

我不明白为什么 React 选择让 onChange 表现得像 onInput 那样。据我所知,我们无法恢复旧的 onChange 行为。文档声称这是“用词不当”,但事实并非如此,它会在发生变化时触发,直到输入也失去焦点。

对于验证,有时我们不想在输入完成之前显示验证错误。或者我们只是不想在每次击键时重新渲染。现在唯一的方法是使用 onBlur 但现在我们还需要手动检查该值是否已更改。

这没什么大不了的,但在我看来,React 扔掉了一个有用的事件,并在已经有一个这样做的事件时偏离了标准行为。

我 100% 同意评论......但我想现在改变它会带来比它解决的更多的问题,因为已经编写了这么多依赖于这种行为的代码。

React 不是官方 Web API 集合的一部分

尽管 React 是建立在 JS 之上的,并且已经看到了巨大的采用率,但作为一项技术,React 的存在是为了将大量功能隐藏在自己的(相当小的)API 下。在事件系统中,这一点很明显,在表面下发生的很多事情实际上与标准 DOM 事件系统完全不同。不仅涉及哪些事件做什么,还涉及何时允许数据保留在事件处理的哪个阶段。您可以在此处阅读更多相关信息:

react事件系统

哇好吧。我有点同意它更像是一个图书馆而不是一个框架,但因此称该段落具有误导性/不真实性??我也不同意框架应该提供 Web 应用程序的所有方面的概念......例如有路由框架,或者像 redux 这样的东西,它是一个状态管理框架。在我看来,一个框架可以让你填充运行中的机器的各个部分。在 Redux 的情况下,您填写 reducers。在 Express 的情况下,您填写请求处理程序和中间件。等等。但至少可以说,这种区别是一个灰色区域。
2021-05-23 03:07:11
完全同意。争论库和框架之间的区别真的是在浪费时间。只取决于您正在工作的抽象级别。
2021-05-25 03:07:11
@rounce 那是一种笼统的声明......哪个部分具有误导性?JSX只是糖衣JS(这是在意见中提出,以另一种答案的声明),因为它直接transpiles到JS(你甚至可以只写JS手动)。React本身就是一个框架,它所做的不仅仅是直接映射到 DOM……请详细说明。
2021-05-27 03:07:11
最后一段具有误导性/不真实。
2021-06-06 03:07:11
React 不是一个框架(它在哪里提供路由、持久性、网络 I/O 管理等?),它是一个提供核心抽象,用于通过平台特定的后端(react-dom、react-native、等等。)。
2021-06-08 03:07:11

没有区别

React 没有默认 'onChange' 事件的行为。我们在react中看到的“onChange”具有默认的“onInput”事件行为。因此,要回答您的问题,两者的react没有区别。我在 GitHub 上提出了一个同样的问题,这就是他们不得不说的:

我认为在做出这个决定的时候(大约 4 年前?),onInput 在浏览器之间不能一致地工作,并且让从其他平台访问网络的人感到困惑,因为他们期望“更改”事件在每次更改时触发。在 React 的情况下,这是一个更大的问题,因为如果您不能尽快处理更改,则受控输入永远不会更新,导致人们认为 React 已损坏。因此,该团队将其称为 onChange。

回想起来,polyfill onInput 并保留其名称而不是更改另一个事件的行为可能是一个更好的主意。但是那艘船已经航行了很久了。我们可能会在未来重新审视这个决定,但我只是鼓励你把它当作 React DOM 的一个怪癖(你会很快习惯)。

https://github.com/facebook/react/issues/9567

此外,本文将提供更多见解。作为缺少默认“onChange”的解决方法,本文建议收听“onBlur”事件。

https://www.peterbe.com/plog/onchange-in-reactjs

我似乎偶然发现了一个差异。React 的 onChange 在选择和替换相同字符的字符时不会触发,onInput 会触发。
2021-06-18 03:07:11

对于那些偶然发现这个问题并寻找一种方法来侦听实际的、基于 DOM 的change事件的人来说,我是这样做的(用 TypeScript 编写):

import { Component, createElement, InputHTMLAttributes } from 'react';

export interface CustomInputProps {
    onChange?: (event: Event) => void;
    onInput?: (event: Event) => void;
}

/**
 * This component restores the 'onChange' and 'onInput' behavior of JavaScript.
 *
 * See:
 * - https://reactjs.org/docs/dom-elements.html#onchange
 * - https://github.com/facebook/react/issues/3964
 * - https://github.com/facebook/react/issues/9657
 * - https://github.com/facebook/react/issues/14857
 */
export class CustomInput extends Component<Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'onInput' | 'ref'> & CustomInputProps> {
    private readonly registerCallbacks  = (element: HTMLInputElement | null) => {
        if (element) {
            element.onchange = this.props.onChange ? this.props.onChange : null;
            element.oninput = this.props.onInput ? this.props.onInput : null;
        }
    };

    public render() {
        return <input ref={this.registerCallbacks} {...this.props} onChange={undefined} onInput={undefined} />;
    }
}

如果您看到改进此方法的方法或遇到问题,请告诉我。与 不同的是blur,该change事件也会在用户按下 Enter 键时触发,并且仅在值实际更改时才会触发。

我仍在获得有关此CustomInput组件的经验例如,复选框的行为很奇怪。我要么在将值传递给复选框时event.target.checkedonChange处理程序中反转要么在将值传递给复选框时checked摆脱这种反转,defaultChecked但这会破坏页面上不同位置表示相同状态的几个复选框保持同步. (在这两种情况下,我都没有将onInput处理程序传递CustomInputfor 复选框。)

真正的救星,谢谢。似乎 React 社区/开发人员陷入了这个问题,但他们可以同意如何解决它。向后兼容性是如此可悲,即使是明显的错误也只是因为很少有人使用该错误作为功能而被保留......我遇到了问题<input type="date/time">,并且onChange甚至因为用户界面导航用户需要选择日期/时间被触发。在普通的 JS 中onchange,当用户关闭 UI 时只触发一次 - 所以当他最终选择日期时。你的这个班让它再次工作:)
2021-05-29 03:07:11

最近我遇到了一个错误,即onChange不允许在 IE11 上的输入字段中进行复制和粘贴。onInput事件将允许这种行为。我在文档中找不到任何描述这一点的文档,但这确实表明两者之间存在差异(预期与否)。

正如您在此处的各种评论中看到的那样,React 将 onChange 和 onInput 视为相同的,而不是争论这个决定的优点。这是解决方案。

当您不想在用户编辑完成之前处理它们时,请使用 onBlur。:)