React'te onChange ve onInput arasındaki fark nedir?


89

Buna bir cevap bulmak için etrafta arama yapmayı denedim, ancak bunların çoğu, onChangebulanıklığın ardından tetikleyicilerin olduğu React bağlamının dışında .

Çeşitli testler yaparken, bu iki olayın nasıl farklı olduğunu (bir metin alanına uygulandığında) söyleyemiyorum. Birisi buna ışık tutabilir mi?


1
Gönderimi daha net olacak şekilde düzenledim. Radyo düğmeleri veya onay kutuları değil, özellikle metin alanı hakkında konuşuyordum.
ffxsam

Bu oldukça yanlış, React sadece JS değil. Ve olaylar bazı durumlarda (gibi onChange) biraz farklı davranır . Ve hayır, metni bir metin alanına yapıştırmak (React'te) hem onChangeve hem de onInput. Bir kemanla test etmekten çekinmeyin ve göreceksiniz.
ffxsam

<input> ve <textarea> için onChange, DOM'un yerleşik oninput olay işleyicisinin yerini alır ve genellikle onun yerine kullanılmalıdır.
Roko C. Buljan

Sanırım onChange daha güvenli bir bahis. Hatta metin alanının değerini programlı olarak değiştirmeye çalıştım, belki onChangetetikleyeceğini ve onInputolmayacağını, ancak her ikisinin de tetikleyeceğini düşündüm .
ffxsam

Evet, biraz React Dokümanlarını inceledikten sonra, React'in jQuery gibi pek çok şey yaptığını, olayları normalleştirdiğini ve evet olduğunu görüyorum. onChange tercih edilen bir yol gibi görünüyor. Ve evet. React, JS'den başka bir şey değildir. Özel bir sihir yok. Sadece kurallar.
Roko C. Buljan

Yanıtlar:


81

Görünüşe göre gerçek bir fark yok

React, bazı nedenlerden dolayı, Component.onChangeDOM element.oninputolayına dinleyiciler ekler . Formlarla ilgili dokümanlardaki nota bakın:

React docs - Formlar

Bu davranışa şaşıran daha fazla insan var. Daha fazla ayrıntı için, React sorun izleyicisindeki bu konuya bakın:

React'in onChange ile onInput # 3964 arasındaki ilişkiyi belgeleyin

Bu konudaki yorumlardan alıntı yapın:

React'in neden onChange'in onInput gibi davranmasını seçtiğini anlamıyorum. Anladığım kadarıyla, eski onChange davranışını geri almanın bir yolu yok. Dokümanlar bunun bir "yanlış isim" olduğunu iddia ediyor, ancak bu gerçekten değil, bir değişiklik olduğunda, giriş de odağı yitirene kadar ateşleniyor.

Doğrulama için, bazen yazmayı bitirene kadar doğrulama hatalarını göstermek istemeyiz. Ya da belki her tuş vuruşunda yeniden render istemiyoruz. Şimdi bunu yapmanın tek yolu onBlur'dur, ancak şimdi değerin manuel olarak değiştiğini de kontrol etmemiz gerekiyor.

O kadar da önemli değil, ama bana öyle geliyor ki React yararlı bir olayı bir kenara attı ve zaten bunu yapan bir olay varken standart davranıştan saptı.

Yoruma% 100 katılıyorum ... Ama şimdi değiştirmenin çözdüğünden daha fazla sorun getireceğini tahmin ediyorum çünkü zaten bu davranışa dayanan çok fazla kod yazılmıştı.

React, resmi Web API koleksiyonunun bir parçası değildir

React, JS'nin üzerine inşa edilmiş ve büyük bir benimsenme oranı görmüş olsa da, çok sayıda işlevi kendi (oldukça küçük) API'si altında gizleyen bir React teknolojisi var. Bunun bariz olduğu alan olay sistemindedir, yüzey altında aslında standart DOM olay sisteminden radikal bir şekilde farklı olan çok şey vardır. Yalnızca hangi olayların ne yaptığı açısından değil, aynı zamanda verilerin olay işlemenin hangi aşamasında kalmasına izin verildiği açısından da. Buradan daha fazlasını okuyabilirsiniz:

React Olay Sistemi


1
Son paragraf yanıltıcı / doğru değil.
rounce

1
Bir çerçeve (burada bu gibi, kalıcılık, ağ I / O yönetimi,? Yönlendirme sağlamak etmez) değildir React, bu bu kütüphane platforma özel arka ucu (aracılığıyla görüntülü ağaçları işlemek için çekirdek Özet sağlar reaksiyona-dom, reaksiyona-yerli vb.).
rounce

7
Vay canına tamam. Bunun bir çerçeveden çok bir kütüphane olduğuna katılıyorum, ancak bu nedenle paragrafı yanıltıcı / yanlış olarak adlandırmak ?? Bir çerçevenin bir web uygulamasının tüm yönlerini sağlaması gerektiği fikrine de katılmıyorum ... Örneğin yönlendirme çerçeveleri veya bir durum yönetimi çerçevesi olan redux gibi şeyler var. Bence bir çerçeve, çalışan bir makinenin parçalarını doldurmanıza izin veriyor. Redux durumunda, redüktörleri doldurursunuz. Express durumunda, istek işleyicileri ve ara yazılımları doldurursunuz. Vb. Ancak ayrım, en azını söylemek için gri bir alandır.
Stijn de Witt

4
Tamamen katılıyorum. Kütüphane ve çerçeve arasındaki ayrım hakkında tartışmak gerçekten zaman kaybıdır. sadece hangi seviyede çalıştığınıza bağlıdır.
swyx

1
@chadsteele Teşekkürler dostum, sana yardım ettiğini duymak harika
Stijn de Witt

23

Hiçbir fark yok

React, varsayılan 'onChange' olayının davranışına sahip değildir. React'te gördüğümüz 'onChange', varsayılan 'onInput' olayının davranışına sahiptir. Yani sorunuza cevap vermek için ikisinin de tepki olarak hiçbir farkı yok. GitHub'da bununla ilgili bir sorun ortaya attım ve bu konuda söyleyecekleri şey bu:

Sanırım bu kararın verildiği sırada (~ 4 yıl önce mi?), OnInput tarayıcılar arasında tutarlı bir şekilde çalışmıyordu ve "değişiklik" olayının "değişiklik" olayının her değişiklikte ateş. React durumunda bu daha büyük bir sorundur, çünkü değişikliği yeterince erken halledemezseniz, kontrollü girdiler asla güncellenmez ve insanları React'in bozuk olduğunu düşünmeye sevk eder. Bu yüzden ekip, bunu Değiştir olarak adlandırmaya başladı.

Geriye dönüp bakıldığında, başka bir olayın davranışını değiştirmek yerine onInput üzerinde çoklu doldurma yapmak ve adını korumak daha iyi bir fikir olabilirdi. Ama o gemi uzun zaman önce yelken açtı. Gelecekte bu kararı tekrar gözden geçirebiliriz, ancak bunu bir React DOM tuhaflığı olarak görmenizi tavsiye ederim (ki buna çok çabuk alışacaksınız).

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

Ayrıca bu makale daha fazla bilgi sağlayacaktır. Varsayılan "onChange" seçeneğinin eksik olması için bir çözüm olarak makale, "onBlur" olayını dinlemeyi önerir.

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


Bir farkla karşılaşmış gibiyim. React'in onChange özelliği, aynı karaktere sahip bir karakter seçilip değiştirildiğinde tetiklenmez, onInput tetikler.
Per Enström

3

Son zamanlarda onChangeIE11'deki giriş alanına kopyalayıp yapıştırmaya izin vermeyen bir hata aldım . Oysa onInputolay bu davranışa izin verirdi. Belgelerde bunu açıklayacak herhangi bir belge bulamadım, ancak bu ikisi arasında (beklenen veya beklenmeyen) bir fark olduğunu gösteriyor.


2

Burada çeşitli yorumlarda görebileceğiniz gibi, React, bu kararın esaslarını tartışmak yerine onChange ve onInput ile aynı şekilde davranır. İşte çözüm.

Kullanıcının düzenlemelerini tamamlanana kadar işlemek istemediğinizde onBlur kullanın. :)


1

Gerçek, DOM tabanlı changeolayı dinlemenin bir yolunu arayan bu sorunu tökezleyen herkes için, bunu böyle yaptım (TypeScript ile yazılmıştır):

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} />;
    }
}

Bu yaklaşımı iyileştirmenin yollarını görürseniz veya onunla ilgili sorunlarla karşılaşırsanız lütfen bana bildirin. Aksine blur,change olay ayrıca kullanıcı enter tuşuna bastığında tetiklenir ve yalnızca değer gerçekten değiştiğinde tetiklenir.

Hala bu CustomInputbileşenle deneyim kazanıyorum . Örneğin, onay kutuları garip davranır. Ben de invert zorunda event.target.checkediçinde onChangeolan onay kutusunun değer geçerken işleyici checkedveya onay kutusunun değer geçerken bu inversiyon kurtulmak defaultCheckedama bu daha sonra sonları o senkronize sayfa keep üzerinde farklı yerlerde aynı devleti temsil eden birkaç onay kutularını . (Her iki durumda da, for onay kutularına bir onInputişleyici göndermedim CustomInput.)


0

Bir fark onChange, aynı karaktere sahip bir karakteri seçip değiştirirken ateşlenmemiş gibi görünüyor.onInput .

Bu korumalı alana bakın: https://codesandbox.io/s/react-onchange-vs-oninput-coggf?file=/src/App.js

  • Alana "A" yazın, ardından tümünü seçin ve "B" yazın. Bu, 2 onChangeve 2 olmak üzere 4 olay tetikleyecektir onInput.
  • Şimdi hepsini seçin ve yeniden "B" yazın, bu yeni bir onInputolayı tetikleyene kadar , ancak hayır onChange.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.