我试过四处寻找答案,但大多数都在 React 的上下文之外,onChange
在模糊时触发。
在执行各种测试时,我似乎无法分辨这两个事件有何不同(当应用于 textarea 时)。任何人都可以对此有所了解吗?
我试过四处寻找答案,但大多数都在 React 的上下文之外,onChange
在模糊时触发。
在执行各种测试时,我似乎无法分辨这两个事件有何不同(当应用于 textarea 时)。任何人都可以对此有所了解吗?
出于某种原因,React 为Component.onChange
DOMelement.oninput
事件附加了侦听器。请参阅表单文档中的注释:
有更多人对这种行为感到惊讶。有关更多详细信息,请参阅 React 问题跟踪器上的此问题:
记录 React 的 onChange 如何与 onInput 相关 #3964
引用关于该问题的评论:
我不明白为什么 React 选择让 onChange 表现得像 onInput 那样。据我所知,我们无法恢复旧的 onChange 行为。文档声称这是“用词不当”,但事实并非如此,它会在发生变化时触发,直到输入也失去焦点。
对于验证,有时我们不想在输入完成之前显示验证错误。或者我们只是不想在每次击键时重新渲染。现在唯一的方法是使用 onBlur 但现在我们还需要手动检查该值是否已更改。
这没什么大不了的,但在我看来,React 扔掉了一个有用的事件,并在已经有一个这样做的事件时偏离了标准行为。
我 100% 同意评论......但我想现在改变它会带来比它解决的更多的问题,因为已经编写了这么多依赖于这种行为的代码。
React 不是官方 Web API 集合的一部分
尽管 React 是建立在 JS 之上的,并且已经看到了巨大的采用率,但作为一项技术,React 的存在是为了将大量功能隐藏在自己的(相当小的)API 下。在事件系统中,这一点很明显,在表面下发生的很多事情实际上与标准 DOM 事件系统完全不同。不仅涉及哪些事件做什么,还涉及何时允许数据保留在事件处理的哪个阶段。您可以在此处阅读更多相关信息:
没有区别
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”事件。
对于那些偶然发现这个问题并寻找一种方法来侦听实际的、基于 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.checked
在onChange
处理程序中反转,要么在将值传递给复选框时checked
摆脱这种反转,defaultChecked
但这会破坏页面上不同位置表示相同状态的几个复选框保持同步. (在这两种情况下,我都没有将onInput
处理程序传递给CustomInput
for 复选框。)
最近我遇到了一个错误,即onChange
不允许在 IE11 上的输入字段中进行复制和粘贴。而onInput
事件将允许这种行为。我在文档中找不到任何描述这一点的文档,但这确实表明两者之间存在差异(预期与否)。
正如您在此处的各种评论中看到的那样,React 将 onChange 和 onInput 视为相同的,而不是争论这个决定的优点。这是解决方案。
当您不想在用户编辑完成之前处理它们时,请使用 onBlur。:)