Pertanyaan saya berkaitan dengan kode Bereaksi, tetapi mungkin saja jawabannya lebih terkait dengan bagaimana Fungsi Acara HTML secara umum daripada Bereaksi.

Saya sedang membangun komponen di mana setiap klik di dalam <div> terlampir harus memicu penangan klik tertentu. Ini mudah diimplementasikan sebagai fungsi onClick yang dilampirkan ke "div induk" ini. Komponen juga berisi kotak centang di dalamnya. Karena aturan bisnis komponen ini, saya ingin agar onClick div induk tidak terpicu oleh klik kotak centang ini.

Pertimbangkan implementasi naif dari komponen ini:

function NaiveComponent() {
  return (
    <div onClick={() => console.log("Clicked parent onClick()")}>
      <label><input type="checkbox" /></label>
      <div> ... </div>
    </div>
  )
} 

Apa yang menurut saya menarik adalah bahwa onClick dipicu dua kali ketika kotak centang diubah, tetapi hanya sekali jika tidak. Saya telah membaca artikel yang menyarankan bahwa ini karena cara klik label disebarkan ke elemen input (seperti yang disarankan oleh React div container onClick konflik dengan checkbox onChange).

Saya juga mencoba menghentikan penyebaran acara klik dengan melampirkan penangan tangkapan berikut ke input. Itu hanya menghentikan salah satu panggilan ke induk onClick dari pemicu.

onClickCapture={e => e.stopPropagation()}

Memperbarui

Saya sepenuhnya mendesain ulang komponen sehingga kotak centang tidak lagi ditempatkan di dalam div dengan penangan klik. Itu adalah desain UI yang buruk sejak awal. Saya pikir masalah penangan klik saya disebabkan oleh lapisan perpustakaan yang digunakan aplikasi saya untuk penataan. Seharusnya jelas bagi saya bahwa apa yang saya lakukan adalah bau kode untuk memulai, berdasarkan kesulitan yang saya hadapi.

Terima kasih semua orang yang memberi jawaban.

0
ecbrodie 31 Januari 2020, 00:07

2 jawaban

Jawaban Terbaik
const App = () => {
  const onCheckboxClick = e => {
    e.stopPropagation();
    alert('checkbox clicked');
  }

  return (
    <div onClick={() => alert('div clicked')}>
      This is the parent div
      <label>
        <input type="checkbox" onClick={onCheckboxClick} />
      </label>
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Ini tampaknya berfungsi dengan baik menggunakan e.stopPropagation(). Bisakah Anda menunjukkan lebih banyak kode Anda jika ini tidak membantu?

1
larz 30 Januari 2020, 21:29

Melampirkan onClick ke input dan menghentikan propagasi akan berhasil. Ini hanya memicu penangan klik input dan bukan yang induknya

function App(){
  return (<div 
    onClick={() => console.log('div clicked')} 
    style={{width: '100px', height:'100px', background: 'blue'}}>
    <input 
       onClick={e => {
         e.stopPropagation(); 
         console.log('check clicked')}} 
       type='checkbox'></input>
    </div>)
}
ReactDOM.render(<App/>, document.getElementById('root'))
1
Michael 30 Januari 2020, 21:31