私はこれに対する答えを探し回ってみましたが、それらのほとんどはReactのコンテキスト外にあり、onChange
ブラー時にトリガーされます。
さまざまなテストを実行しているときに、これら2つのイベントがどのように異なるのか(テキスト領域に適用した場合)がわかりません。誰かがこれに光を当てることができますか?
私はこれに対する答えを探し回ってみましたが、それらのほとんどはReactのコンテキスト外にあり、onChange
ブラー時にトリガーされます。
さまざまなテストを実行しているときに、これら2つのイベントがどのように異なるのか(テキスト領域に適用した場合)がわかりません。誰かがこれに光を当てることができますか?
onChange
)。いいえ、(Reactの)textareaにテキストを貼り付けるonChange
と、との両方がトリガーされますonInput
。気軽にフィドルでテストしてみてください。
onChange
トリガーさonInput
れるか、トリガーされないかを考えましたが、両方ともトリガーされます。
回答:
Reactは、何らかの理由で、リスナーをComponent.onChange
DOMelement.oninput
イベントにアタッチします。フォームに関するドキュメントの注記を参照してください。
この振る舞いに驚かされる人はもっといます。詳細については、React課題トラッカーでこの課題を参照してください。
ReactのonChangeがonInput#3964にどのように関連しているかを文書化します
その問題に関するコメントからの引用:
ReactがonChangeをonInputのように動作させることを選択した理由がわかりません。私が知る限り、古いonChangeの動作を元に戻す方法はありません。ドキュメントは、それが「誤称」であると主張していますが、実際にはそうではありません。入力もフォーカスを失うまでではなく、変更があったときに起動します。
検証のために、入力が完了するまで検証エラーを表示したくない場合があります。あるいは、キーストロークごとに再レンダリングしたくないだけかもしれません。これを行う唯一の方法はonBlurを使用することですが、値が手動で変更されたことも確認する必要があります。
それほど大したことではありませんが、Reactが有用なイベントを破棄し、これを行うイベントがすでに存在するときに標準の動作から逸脱したように思えます。
コメントに100%同意します...しかし、この動作に依存するコードが既に作成されているため、今すぐ変更すると、解決するよりも多くの問題が発生すると思います。
Reactは公式のWebAPIコレクションの一部ではありません
ReactはJSの上に構築されており、非常に高い採用率を誇っていますが、テクノロジーとしてReactは、独自の(かなり小さい)APIの下に多くの機能を隠すために存在しています。これが明らかな領域はイベントシステムであり、実際には標準のDOMイベントシステムとは根本的に異なる多くのことが表面下で行われています。どのイベントが何を実行するかという点だけでなく、イベント処理のどの段階でデータをいつ保持できるかという点でも。あなたはここでそれについてもっと読むことができます:
違いはありません
Reactには、デフォルトの「onChange」イベントの動作はありません。reactに表示される「onChange」には、デフォルトの「onInput」イベントの動作があります。だからあなたの質問に答えるために、反応の両方に違いはありません。私は同じことに関してGitHubで問題を提起しました、そしてこれは彼らがそれについて言わなければならないことです:
この決定が下された時点(約4年前?)では、onInputはブラウザー間で一貫して機能せず、他のプラットフォームからWebにアクセスする人々は、「変更」イベントを予期していたため、混乱していたと思います。すべての変更で発砲します。Reactの場合、変更をすぐに処理できないと、制御された入力が更新されず、Reactが壊れていると思われるため、より大きな問題になります。そのため、チームはそれをonChangeと呼びました。
振り返ってみると、別のイベントの動作を変更するよりも、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
、これにより、ページの異なる場所で同じ状態を表すいくつかのチェックボックスが同期し続けることが壊れます。(どちらの場合も、forチェックボックスにonInput
ハンドラーを渡しませんでしたCustomInput
。)
一つの違いは、それがあるように思わonChange
選択し、同じ文字と文字を交換するときながら、解雇されていないonInput
です。
このサンドボックスを参照してください:https://codesandbox.io/s/react-onchange-vs-oninput-coggf?file = / src / App.js
onChange
と2の4つのイベントがトリガーされますonInput
。onInput
イベントがトリガーされますが、トリガーされませんonChange
。