Javascript 在React中,什么';onChange和onInput之间的区别是什么?

Javascript 在React中,什么';onChange和onInput之间的区别是什么?,javascript,reactjs,dom-events,Javascript,Reactjs,Dom Events,我已经试着四处搜索这个问题的答案,但大多数都不在React的上下文中,在React中,onChange会在模糊时触发 在执行各种测试时,我似乎无法判断这两个事件有何不同(当应用于textarea时)。有人能解释一下吗?似乎没有什么真正的区别 出于某种原因,React会将Component.onChange的侦听器附加到DOM元素.oninput事件。请参见表格上文档中的注释: 更多的人对这种行为感到惊讶。有关更多详细信息,请参阅React issue tracker上的此问题: 引述对该问题

我已经试着四处搜索这个问题的答案,但大多数都不在React的上下文中,在React中,
onChange
会在模糊时触发

在执行各种测试时,我似乎无法判断这两个事件有何不同(当应用于textarea时)。有人能解释一下吗?

似乎没有什么真正的区别 出于某种原因,React会将
Component.onChange
的侦听器附加到DOM
元素.oninput
事件。请参见表格上文档中的注释:

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

引述对该问题的评论:

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

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

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

我百分之百同意这个评论。。。但我想现在更改它会带来比它解决的问题更多的问题,因为已经编写了太多依赖于此行为的代码

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

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


没有区别

React没有默认“onChange”事件的行为。我们在react中看到的“onChange”具有默认的“onInput”事件行为。所以要回答你的问题,它们在反应上没有区别。我在GitHub上提出了一个关于这一点的问题,这就是他们对此的看法:

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

回想起来,最好是对输入进行多填充并保留其名称,而不是更改另一个事件的行为。但是那艘船已经航行很久了。将来我们可能会重新考虑这个决定,但我鼓励您将其视为React DOM的一个怪癖(您很快就会习惯)

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


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

正如您在这里的各种评论中所看到的,React treats onChange and onInput the same等,而不是讨论这一决定的优点。这是解决办法


如果不希望在用户编辑完成之前处理这些编辑,请使用onBlur.:)

如果有人在这个问题上遇到困难,想寻找一种方法来监听实际的、基于DOM的
更改
事件,我就是这样做的(用TypeScript编写的):

从'react'导入{Component,createElement,inputtmlattributes};
导出接口CustomInputProps{
onChange?:(事件:事件)=>作废;
onInput?:(事件:事件)=>无效;
}
/**
*此组件恢复JavaScript的“onChange”和“onInput”行为。
*
*见:
* - 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
*/
导出类CustomInput扩展组件{
私有只读寄存器回调=(元素:HTMLInputElement | null)=>{
if(元素){
element.onchange=this.props.onchange?this.props.onchange:null;
element.oninput=this.props.oninput?this.props.oninput:null;
}
};
公共渲染(){
返回;
}
}
请让我知道,如果你看到改进这种方法的方法或遇到问题。与
模糊
不同,
更改
事件也会在用户按enter键时触发,并且仅当值实际更改时才会触发

我仍然在积累使用这个
CustomInput
组件的经验。例如,复选框的行为异常。我要么必须在
onChange
处理程序中反转
event.target.checked,同时使用
checked
将值传递给复选框,要么在使用
defaultChecked将值传递给复选框时取消此反转
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} />;
    }
}