Реагировать / HTML отменить onClick от родителя <div>при выборе дочернего флажка <input> - PullRequest
0 голосов
/ 31 января 2020

Мой вопрос относится к коду React, но возможно, что ответ больше связан с тем, как HTML События функционируют в целом, а не с React.

Я создаю компонент, в котором любой щелчок внутри вложенного элемента <div> должен вызвать определенный c обработчик щелчка. Это легко реализовать как функцию onClick, прикрепленную к этому «родительскому div». Компонент также содержит флажок внутри него. Из-за бизнес-правил этого компонента, я не хочу, чтобы родительский div onClick срабатывал при нажатии этого флажка.

Рассмотрим эту наивную реализацию этого компонента:

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

Что мне показалось интересным, так это то, что onClick запускается дважды при смене флажка, но только один раз в противном случае. Я читал статьи, которые предполагают, что это связано с тем, как щелчки меток распространяются на элемент ввода (как подсказывает Контейнер React div onClick конфликтует с флажком onChange ).

У меня есть также попытался остановить распространение события click, подключив к входу следующий обработчик захвата. Он только остановил один из вызовов родительского onClick от запуска.

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

Обновление

Я полностью изменил дизайн компонента, чтобы флажок больше не помещался в div с обработчиком кликов. Во-первых, это был плохой дизайн интерфейса. Я думаю, что мои проблемы с обработчиками кликов были вызваны слоями библиотек, которые мое приложение использует для стилей. Для меня должно было быть очевидно, что то, что я делал, было запахом кода, исходя из трудности, с которой я столкнулся.

Спасибо всем, кто дал ответ.

Ответы [ 2 ]

1 голос
/ 31 января 2020

Присоединение onClick к входу и остановка распространения должны работать. Это только вызывает обработчик щелчка ввода, а не родительский

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 голос
/ 31 января 2020

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>

Кажется, это нормально работает с использованием e.stopPropagation(). Можете ли вы показать нам больше своего кода, если это не поможет?

...