Как настроить прослушиватель событий и удалить его после первого запущенного события с помощью реагирующих хуков?

Я хочу настроить прослушиватель событий, чтобы получать событие только первыйtouchstart в window. Как только это произойдет, я хочу удалить этого слушателя.

Я использую React Hooks.

ВОПРОС

Я хочу знать, правильно ли это или есть лучший подход:

useEffect(() => {
    function onFirstTouch() {
      setWindowTouch(true);
      window.removeEventListener('touchstart', onFirstTouch, false);
    }
    window.addEventListener('touchstart', onFirstTouch);
  }, []);

Это кажется правильным, но также кажется, что я собираюсь снова установить прослушиватель, когда мой компонент размонтируется.


ПРИМЕЧАНИЕ:

Я знаю, что мог бы сделать что-то подобное (используйте «hasTouched» ref, чтобы проверить, не было ли уже запущено первое событие, и игнорировать последующие события), но это не совсем одно и то же.

useEffect(() => {

    function handleTouch() {
      if (hasTouched.current === true) {
        return;
      }
      hasTouched.current = true;
      setWindowTouch(true);
    }

    window.addEventListener('touchstart', handleTouch);
    return () => window.removeEventListener('touchstart', handleTouch);
  }, []);
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
391
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Поэтому я бы изменил его на следующее:

useEffect(() => {
    function onFirstTouch() {
      // The order of these two lines shouldn't really matter, but I would
      // remove the listener before triggering a re-render via setWindowTouch
      window.removeEventListener('touchstart', onFirstTouch);
      setWindowTouch(true);
    }
    window.addEventListener('touchstart', onFirstTouch);
    return () => window.removeEventListener('touchstart', onFirstTouch);
  }, []);

Касательно:

feels that I'm going to set the listener again, when my component gets unmounted

Единственное, что будет выполнено при размонтировании, — это возвращаемая функция (т.е. () => window.removeEventListener('touchstart', onFirstTouch)). Он снова установит прослушиватель только в том случае, если компонент будет повторно смонтирован.

Я всегда думал, что если я использую и empty dependency array [ ], мой эффект будет работать после 1-го рендера, а также после размонтирования. Но из того, что вы указали, теперь я понимаю, что он будет работать после 1-го рендеринга, и только возвращаемая функция будет работать после размонтирования, верно? Просто чтобы прояснить ситуацию, что, если я не передам функцию возврата (все еще используя пустой массив [ ])? Означает ли это, что мой эффект будет работать после 1-го рендера, и ничего не будет работать после размонтирования? Это тоже правильно? Спасибо!

cbdeveloper 13.05.2019 17:43

Правильный. При использовании пустого массива зависимостей эффект выполняется только один раз (при монтировании), а очистка выполняется только один раз (при размонтировании). Если вы не укажете функцию очистки, то при размонтировании ничего не запустится.

Ryan Cogswell 13.05.2019 17:48

Я предложил небольшое изменение в формулировке документации. Посмотрите на мое изменение здесь и посмотрите, помогло бы это избежать путаницы.

Ryan Cogswell 13.05.2019 18:17

Я думаю, это очень помогает! Это именно та строчка, которая раньше вызывала у меня непонимание. Спасибо!

cbdeveloper 13.05.2019 18:21

Другие вопросы по теме