React: Ubah pengaktifan acara beberapa kali sebelum komposisi IME berakhir

Dibuat pada 21 Mei 2015  ·  48Komentar  ·  Sumber: facebook/react

Detail ekstra


Masalah Asli

Ketika saya mencoba contoh ini dari https://facebook.github.io/react/blog/2013/11/05/thinking-in-react.html , setiap karakter China yang dimasukkan oleh metode masukan pinyin China akan mengaktifkan terlalu banyak render seperti :

screen shot 2015-05-21 at 14 04 36

Sebenarnya saya berharap mereka tidak menembak sebelum saya mengkonfirmasi karakter China.

Kemudian saya mencoba jenis metode masukan lain - metode masukan wubi, saya mendapatkan ini:

screen shot 2015-05-21 at 14 17 15

Aneh juga. Jadi saya melakukan tes di jQuery :

screen shot 2015-05-21 at 14 05 12

Hanya setelah saya menekan spasi untuk mengonfirmasi karakter, peristiwa keyup akan aktif.

Saya tahu itu mungkin berbeda antara implementasi jQuery keyup dan bereaksi onChange , tetapi saya akan mengharapkan cara bagaimana jQuery keyup menangani karakter Cina daripada bereaksi onChange .

DOM Bug

Komentar yang paling membantu

Halo, teman-teman Facebook, sebenarnya masalah ini menyebabkan masalah SERIUS : kami tidak dapat memperbarui input secara asinkron dengan input bahasa Mandarin.
Misalnya, kami tidak dapat menggunakan sumber data reaktif meteor atau penyimpanan seperti redux, karena semua umpan balik diperbarui secara asinkron.
Berikut adalah contoh paling sederhana untuk menunjukkan masalah ini, ini menggunakan setTimeout untuk melakukan pembaruan async:
https://jsfiddle.net/liyatang/bq6oss6z/1/

Saya sangat berharap Anda dapat memperbaikinya dengan cepat, sehingga kami tidak akan menyia-nyiakan upaya untuk mengatasinya di sana-sini dan lagi dan lagi.

Terima kasih.

Inilah solusi saya. Jika ada yang menghadapi masalah yang sama, Anda dapat melihatnya

Semua 48 komentar

cc @salier :) - Apa yang harus kita lakukan di sini?

Saya pikir kita tidak harus mengaktifkan onChange sampai string IME dilakukan.

Salah satu cara untuk menangani ini di ChangeEventPlugin adalah dengan mengabaikan semua peristiwa input antara compositionstart dan compositionend , kemudian gunakan peristiwa input segera mengikuti compositionend .

Saya melakukan beberapa pengujian cepat pada OSX Chrome dan Firefox dengan Simplified Pinyin dan 2-Set Korean, dan urutan acara serta data tampaknya cukup benar. (Saya memperkirakan bahwa kita akan mengalami masalah dengan IE Korea, tetapi kita mungkin beruntung.)

Saya pikir kami mungkin terus mengalami masalah dengan metode masukan alternatif seperti ekstensi Google Input Tools, tetapi mungkin ada solusi untuk itu.

Ini juga memengaruhi cara karakter dialektik diketik untuk bahasa latin. Bahkan tekan lama e dan kemudian gunakan varian gagal di sini.

Maaf ini sepertinya tidak ada hubungannya. Permintaan maaf saya.

Apakah ada pembaruan? Menderita masalah ini juga.

Tidak ada saat ini - ini bukan prioritas tinggi bagi kami saat ini. Saya akan dengan senang hati melihat permintaan tarik jika ada yang mau memperbaiki ini.

@salier Sepertinya IE tidak mengaktifkan acara input setelah compositionend . Saya telah menguji pada IE11 dan Edge pada Windows 10. Ini menyala dengan benar di Chrome dan Firefox.

dalam contoh 9, peristiwa Perubahan diaktifkan terlalu banyak saat memasukkan karakter Cina lagi

Halo, teman-teman Facebook, sebenarnya masalah ini menyebabkan masalah SERIUS : kami tidak dapat memperbarui input secara asinkron dengan input bahasa Mandarin.
Misalnya, kami tidak dapat menggunakan sumber data reaktif meteor atau penyimpanan seperti redux, karena semua umpan balik diperbarui secara asinkron.
Berikut adalah contoh paling sederhana untuk menunjukkan masalah ini, ini menggunakan setTimeout untuk melakukan pembaruan async:
https://jsfiddle.net/liyatang/bq6oss6z/1/

Saya sangat berharap Anda dapat memperbaikinya dengan cepat, sehingga kami tidak akan menyia-nyiakan upaya untuk mengatasinya di sana-sini dan lagi dan lagi.

Terima kasih.

Inilah solusi saya. Jika ada yang menghadapi masalah yang sama, Anda dapat melihatnya

Saya membuat contoh sederhana untuk mendemonstrasikan cara menggunakan peristiwa compositionstart dan compositionend untuk mencegah penginputan IME Cina pada onchange peristiwa.
Ini tautannya: https://jsfiddle.net/eyesofkids/dcxvas28/8/

@eyesofkids kerja bagus, ini bisa dijadikan implementasi default dari onChange untuk input, textarea ...

kerja bagus !

Saya mengalami masalah yang sama dan solusi @eyesofkids bekerja dengan sempurna (terima kasih!).

Setelah menyelesaikannya, saya menyelami kode sumber React untuk setidaknya mencoba menambahkan tes yang gagal untuk ini — berharap untuk menambahkan perilaku yang diharapkan ke perpustakaan nanti — meskipun tampaknya agak rumit bagi seseorang yang tidak terbiasa dengan internal.

Awalnya saya mengharapkan bahwa tes yang mirip dengan apa yang sudah tersedia untuk ChangeEventPlugin seharusnya berfungsi, yaitu simulasi asli compositionStart / compositionUpdate dan tidak memeriksa onChange callback adalah dipecat; juga memeriksa onChange hanya akan dipecat setelah compositionEnd disimulasikan. Namun ini sepertinya tidak berhasil.

Oleh karena itu saya berpikir bahwa mungkin memeriksa ChangeEventPlugin.extractEvents() akan menjadi pendekatan yang layak, mirip dengan apa yang dilakukan dalam pengujian untuk SelectEventPlugin . Di sini untuk beberapa alasan saya selalu mendapatkan undefined saat mengekstrak acara sekalipun.
Untuk referensi, ini adalah kode tes yang saya coba dalam _ChangeEventPlugin-test.js_:

  var EventConstants = require('EventConstants');
  var ReactDOMComponentTree = require('ReactDOMComponentTree');
  var topLevelTypes = EventConstants.topLevelTypes;

  function extract(node, topLevelEvent) {
    return ChangeEventPlugin.extractEvents(
      topLevelEvent,
      ReactDOMComponentTree.getInstanceFromNode(node),
      {target: node},
      node
    );
  }

  function cb(e) {
    expect(e.type).toBe('change');
  }
  var input = ReactTestUtils.renderIntoDocument(
    <input onChange={cb} value='foo' />
  );

  ReactTestUtils.SimulateNative.compositionStart(input);

  var change = extract(input, topLevelTypes.topChange);
  expect(change).toBe(null);

Saya khawatir saya tidak tahu persis bagaimana seharusnya men-debug tes ini — jika tidak, saya akan memiliki gambaran yang lebih jelas tentang apa yang terjadi. Setiap panduan tentang bagaimana melanjutkan atau petunjuk lainnya akan sangat dihargai.

Solusi tiba-tiba rusak di Chrome 53+ dan tampaknya tidak berlaku lagi karena mereka mengubah urutan compositionend dipecat : sebelumnya terjadi sebelum textInput , sekarang setelah textInput . Sebagai akibatnya, change tidak akan dipecat jika dibatalkan saat dalam komposisi 😕.

https://github.com/suhaotian/react-input mungkin membantu seseorang

Ada solusi rumit untuk Chrome v53. Untuk memanggil perubahan pegangan setelah compositionend dipecat.

handleComposition  = (event) => {

    if(event.type === 'compositionend'){
      onComposition = false

      //fire change method to update for Chrome v53
      this.handleChange(event)

    } else{
      onComposition = true
    }
  }

periksa demo di sini: https://jsfiddle.net/eyesofkids/dcxvas28/11/

@chenxsan sudah menemukan solusinya?
Anda bisa mendeteksi komposisiStart dan membiarkan variabel sama dengan true.
Kemudian untuk menggunakan variabel, yang Anda setel, di onChange untuk melihat apakah itu harus mengaktifkan kueri

Saya telah mengirimkan masalah baru untuk komponen terkontrol di # 8683

Solusi sementara untuk komponen yang tidak terkontrol dan terkontrol (input, textarea) diunggah ke kejadian komposisi reaksi .

@yesmeck sangat senang melihat berita ini.

Saya melihat pengujian hanya fokus pada Webkit, itu harus dipisahkan ke dalam Chrome dan Safari karena Chrome mengubah pesanan yang dipicu peristiwa compositionend setelah 53+.

@eyesofkids Menambahkan kasus pengujian baru untuk Chrome di bawah 53.

Hanya untuk menambahkan bahan bakar ke dalam api, saya telah mencoba untuk mengatasi masalah ini dan menemukan bahwa versi iOS safari saat ini tidak memicu peristiwa compositionend saat menggunakan IME Hiragana Jepang, saya pikir ini disengaja karena menu komposisi sepertinya tidak pernah ditutup.
Pada contoh @eyesofkids, solusi inputValue tidak pernah diperbarui, meskipun bagi saya https://github.com/zhaoyao91/react-optimistic-input memperbaiki masalah dengan IME Jepang.

Bagi siapa pun yang mencari solusi untuk ini, berikut adalah komponen yang siap digunakan. https://github.com/aprilandjan/react-starter/blob/test/search-input/src/components/SearchInput.js Cukup gunakan sebagai ganti elemen input teks biasa dan semuanya baik-baik saja.

@ zhaoyao91 solusi Anda berhasil! Terima kasih banyak.

hai teman-teman beberapa berita tentang masalah ini?

Ini bukan prioritas tinggi karena pengaktifan onChange terlalu sering jarang menimbulkan masalah. Di mana hal itu menyebabkan masalah pada aplikasi Anda?

@sophiebits maaf tidak sengaja mengklik 'X'. Ini dapat menurunkan kinerja jika ada operasi pemfilteran atau panggilan balik server yang digunakan dalam penangan peristiwa perubahan. Pendekatan yang ditampilkan di https://github.com/facebook/react/issues/3926#issuecomment -316049951 adalah solusi yang bagus untuk input yang tidak terkontrol atau asli tetapi tidak memetakan dengan baik ke input yang dikontrol React. Sepertinya beberapa di utas ini telah mencoba mengembangkan PR tetapi menemukan internal agak rumit - tetapi mungkin seorang insinyur di tim Anda dapat membuatnya bekerja lebih cepat? https://github.com/facebook/react/issues/8683 adalah deskripsi yang jauh lebih baik tentang IMO masalah sebenarnya.

Adakah yang bisa membantu saya memahami: apakah masalahnya hanya pada panggilan onChange di tengah ? Atau apakah Anda mendapatkan nilai yang salah pada akhirnya?

Pengujian dari upaya perbaikan di https://github.com/facebook/react/pull/8438 lolos jika saya menghapus pernyataan tentang berapa kali onChange dipanggil. Jadi saya kira masalah ini hanya tentang panggilan tambahan onChange .

tidak ada panggilan onChange tambahan, itu hanya mendapatkan nilai yang salah di akhir, tampaknya lebih seperti masalah onComposition.

@ Crochefluid Dapatkah Anda membuat tes yang gagal untuk ini? Mirip dengan apa yang # 8438 coba lakukan. Dalam tes itu, tidak ada nilai yang salah.

@gaearon Saya akan mencobanya. Apakah Anda mencoba tes itu di safari (mac / IOS)?

Ini adalah tes Node tetapi menyandikan urutan yang diambil dari browser dan perangkat yang berbeda. Silakan lihat sumbernya. Anda perlu menambahkan urutan yang gagal.

Jadi saya kira masalah ini hanya tentang panggilan onChange tambahan.

Persis.

Saya masih mendapatkan masalah ini. Sepertinya masalah ini telah dibuka selama 3 tahun, apakah saat ini React mendukung input berbahasa Mandarin di komponen yang dikontrol?

Juga melihat ini dalam bahasa Jepang dengan karakter tertentu ...

Berikut kotak pasir kode yang mereproduksi masalah saya. Sepertinya ini terkait dengan formulir. Menggunakan input secara langsung tidak masalah.

https://codesandbox.io/s/0m1760xqnl

Saya menambahkan beberapa kasus:
Menggunakan status reaksi dan input biasa tidak masalah
Menggunakan status reaksi, bentuk biasa, dan masukan biasa baik-baik saja
Kami menggunakan komponen formulir berbasis konteks yang tidak berfungsi. Ini mungkin masalah terkait konteks.

Masalah terpecahkan: Saya membuatnya berfungsi di codepen. Untuk beberapa alasan meneruskan 'input' sebagai sebuah komponen bekerja, ketika meneruskan (props) => tidak.

Ada yang tahu apa bedanya?

Sebenarnya, saya juga sudah mencoba:

Bekerja

<Field {...otherProps} component="input" />

Tidak berhasil

<Field {...otherProps} component={(props) => <input {...props} />} />

Bekerja dengan cukup aneh

const WrappedInput = (props) => <input {...props} />
...
<Field {...otherProps} component={WrappedInput} />

Jelas ada keajaiban terjadi di sini yang tidak saya mengerti. 😕

Ada pembaruan?

Tampaknya menyebabkan hasil yang salah saat IME diaktifkan

e84721f3ec71a5ce043ef8290

Saya pernah mengalami masalah yang sama dengan @otakustay
Tampaknya tidak mungkin untuk mendukung masukan terkontrol dengan masukan IME. Saya telah menelusuri urutan kejadian sebagai berikut.

  1. Pengguna mengetik surat, katakan w
  2. onChange dipicu
  3. Negara diperbarui dengan nilai baru
  4. Nilai baru disebarkan ke input melalui atribut value .
  5. "Komposisi" IME terputus pada saat ini

    • Ada string w dalam elemen input

    • Ada juga string w disimpan di buffer IME

  6. Pengguna mengetik huruf lain, katakan a
  7. String dalam input a digabungkan dengan string buffer IME untuk menghasilkan wwa .
  8. Ulangi langkah 1-7 untuk mendapatkan banyak karakter duplikat.

Saya perhatikan bahwa bug hanya terjadi jika input merender > 15 md setelah acara ComposationUpdate setelah pengecatan ulang berikutnya.

Saat ini satu-satunya solusi saya adalah beralih dari input yang dikontrol.

Sunting : Ini reproduksi sederhana: https://jsfiddle.net/kbhg3xna/
Sunting2 : Ini solusi hacky saya: https://jsfiddle.net/m792qtys/ cc: @otakustay

Ada pembaruan tentang ini?

perbarui ??

Ada pembaruan tentang ini?

Tertegun, saya dihadapkan pada pertanyaan ini

Menariknya, terlihat masalahnya bukan hanya tentang multi-times onChange. Jika kita tidak setState antara onCompositionStart dan onCompositionEnd , react akan "mengontrol" nilai apa adanya. Tindakan ini akan mengganggu komposisi. Itu berarti kita tidak akan mendapatkan acara onCompositionEnd ...... (Jika saya salah sebutkan saya tlg.) Tetapi kita hanya dapat mengubah status segera (Jika tidak, kita harus menghadapi masalah @ knubie menyebutkan). Reproduksi di sini (Sepertinya komponen "setengah terkontrol"): https://gist.github.com/cpdyj/6567437d96c315e9162778c8efdfb6e8

Tapi saya sangat terkejut masalahnya tidak dapat diperbaiki selama lima tahun 😢

@hellendag Saya rasa kita tidak harus mengaktifkan onChange sampai string IME dilakukan.

Saya tidak berpikir ini adalah solusi yang valid karena komponen mungkin ingin mengetahui string IME "tidak terikat" untuk misalnya opsi pemfilteran dalam daftar saat pengguna mengetik.

Saya tidak yakin apakah pendekatan yang saya gunakan di utas lain ini dapat membantu mereka yang mengalami masalah ini, tetapi inilah tautan untuk berjaga-jaga: https://github.com/facebook/react/issues/13104#issuecomment -691393940

ada pembaruan?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat