#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 },
Комментариев нет:
Отправить комментарий