Berikut adalah komponen dasarnya. Baik <ul>
dan <li>
memiliki fungsi onClick. Saya hanya ingin onClick yang <li>
menyala, bukan <ul>
. Bagaimana saya bisa mencapai ini?
Saya telah bermain-main dengan e.preventDefault (), e.stopPropagation (), tetapi tidak berhasil.
class List extends React.Component {
constructor(props) {
super(props);
}
handleClick() {
// do something
}
render() {
return (
<ul
onClick={(e) => {
console.log('parent');
this.handleClick();
}}
>
<li
onClick={(e) => {
console.log('child');
// prevent default? prevent propagation?
this.handleClick();
}}
>
</li>
</ul>
)
}
}
// => parent
// => child
reactjs
onclick
event-propagation
dmwong2268.dll
sumber
sumber
Jawaban:
Saya memiliki masalah yang sama. Saya menemukan stopPropagation melakukan pekerjaan. Saya akan membagi item daftar menjadi komponen terpisah, sebagai berikut:
sumber
this.props.handleClick()
dalamListItem
komponenthis.props.click
?<Link>
React menggunakan event delegation dengan satu event listener pada dokumen untuk event yang menggelembung, seperti 'click' dalam contoh ini, yang berarti menghentikan propagasi tidak dimungkinkan; acara nyata telah disebarkan pada saat Anda berinteraksi dengannya di React. stopPropagation pada kejadian sintetis React dimungkinkan karena React menangani penyebaran kejadian sintetis secara internal.
sumber
document.addEventListener('click')
dikombinasikan dengan react'sonClick
Di urutan peristiwa DOM: MENANGKAP vs BUBBLING
Ada dua tahap bagaimana peristiwa disebarkan. Ini disebut "menangkap" dan "menggelegak" .
Tahap penangkapan terjadi terlebih dahulu, kemudian dilanjutkan dengan tahap penggelembungan. Saat Anda mendaftarkan acara menggunakan api DOM reguler, acara tersebut akan menjadi bagian dari tahap menggelembung secara default, tetapi ini dapat ditentukan saat pembuatan acara
Di React, acara menggelegak juga yang Anda gunakan secara default.
Mari kita lihat di dalam callback handleClick (React):
Alternatif yang belum saya lihat disebutkan di sini
Jika Anda memanggil e.preventDefault () di semua acara Anda, Anda bisa memeriksa apakah sebuah acara telah ditangani, dan mencegahnya ditangani lagi:
Untuk perbedaan antara kejadian sintetis dan kejadian asli, lihat dokumentasi React: https://reactjs.org/docs/events.html
sumber
Ini tidak 100% ideal, tetapi jika terlalu menyakitkan untuk diturunkan
props
pada anak-anak -> busana anak-anak atau buatContext.Provider
/Context.Consumer
hanya untuk tujuan ini), dan Anda berurusan dengan perpustakaan lain yang memiliki penangannya sendiri yang menjalankannya sebelum milik Anda, Anda juga dapat mencoba:Dari apa yang saya pahami,
event.persist
metode ini mencegah sebuah objek segera dilemparkan kembali keSyntheticEvent
pool React . Jadi karena itu,event
pass di React sebenarnya tidak ada saat Anda meraihnya! Ini terjadi pada cucu karena cara React menangani masalah internal dengan terlebih dahulu memeriksa orang tuaSyntheticEvent
penangannya (terutama jika orang tua memiliki panggilan balik).Selama Anda tidak memanggil
persist
sesuatu yang akan menciptakan memori yang signifikan untuk terus membuat acara sepertionMouseMove
(dan Anda tidak membuat semacam permainan Cookie Clicker seperti Kue Nenek), itu akan baik-baik saja!Juga perhatikan: dari membaca sekitar GitHub mereka sesekali, kita harus terus mengawasi versi React yang akan datang karena mereka pada akhirnya dapat menyelesaikan beberapa masalah dengan ini karena mereka tampaknya akan membuat kode React lipat dalam kompiler / transpiler.
sumber
Saya mengalami masalah dalam
event.stopPropagation()
bekerja. Jika Anda juga melakukannya, coba pindahkan ke bagian atas fungsi handler klik Anda, itulah yang perlu saya lakukan untuk menghentikan acara menggelembung. Fungsi contoh:sumber
Anda dapat menghindari acara menggelembung dengan memeriksa target acara.
Misalnya jika Anda memiliki masukan yang bersarang ke elemen div di mana Anda memiliki penangan untuk peristiwa klik, dan Anda tidak ingin menanganinya, saat masukan diklik, Anda bisa meneruskan
event.target
ke penangan Anda dan memeriksa apakah penangan harus dijalankan berdasarkan properti target.Misalnya Anda dapat memeriksa
if (target.localName === "input") { return}
.Jadi, ini adalah cara untuk "menghindari" eksekusi penangan
sumber
Cara baru untuk melakukan ini jauh lebih sederhana dan akan menghemat waktu Anda! Cukup teruskan peristiwa tersebut ke penangan klik asli dan panggil
preventDefault();
.sumber