Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

stopPropagation для отмены изменения state в React

#javascript #reactjs #события


Есть функция, которая меняет состояние state, срабатывающая при клике на внутреннем
элементе:

toggleModal(typeModal){
  this.setState({
    [typeModal]: !this.state[typeModal]
  });
}


При клике вне элемента состояние state должно изменяться:

closeModal(typeModal){
  this.setState({
    [typeModal]: false
  });
}


closeModal вещаем на onClick у контейнера, например, Body. 

Вопрос: как запретить всплытие изменения состояния на элементе?
(return false; и event.stopPropagation() не работают)
    


Ответы

Ответ 1



1. Информация в вопросе слегка неполна и противоречива. Начнем, с того что согласно документации event.stopPropagation лучше применять с версии 0.14, до нее можно возвращать false у обработчика. И если Вы обрабатываете все с помощью реактовской системы событий, все должно работать. 2. Proof of concept: jsfiddle. Только с реактовскими событиями, обработчик клика висит на контейнере. 3. Значит остается достать хрустальный шар и угадать что не работает у вас. Вероятнее всего Вы мешаете реактовские события с браузерными. closeModal вещаем на onClick у контейнера, например, Body. Т.е. body это у вас не ректовский компонент а самое что ни на есть document.body с событием onclick. React использует свою систему синтетических событий. Физически, по крайней мере для всплывающих событий это один обработчик на document, дальше используется делегирование. Поэтому такой подход напрямую не сработает: к моменту когда событие до реактовского обработчика дойдет, оно уже всплыло. 4. Окей, как тогда мне ловить клик снаружи компонента? Можно сделать например так: jsfiddle. Смысл в том что пока компонент существует, на document висит наш обработчик клика. Срабатывание его при клике на сам компонент мы обрабатываем ручками в самом обработчике. Если у вас устаревшая версия реакта, (<0.14), то апи может быть чуть чуть другим, но смысл от же. Магия происходит здесь: // Привязываем-отвязываем обработчик на документ, соответственно жизненному циклу компонента componentWillMount: function () { document.addEventListener('click', this.unStrike, false); }, componentWillUnmount: function () { document.removeEventListener('click', this.unStrike, false); }, и здесь: unStrike: function(event){ // предотвращаем срабатывание на самом элементе if (ReactDOM.findDOMNode(this).contains(event.target)) { return; } // smth else },

Комментариев нет:

Отправить комментарий