Я хочу настроить прослушиватель событий, чтобы получать событие только первый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);
}, []);





Основная проблема, которую я вижу, заключается в том, что вам нужно очистить прослушиватель при размонтировании на случай, если касание никогда не произойдет, чтобы касание после размонтирования не пыталось воздействовать на ваш размонтированный компонент.
Поэтому я бы изменил его на следующее:
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-го рендера, и ничего не будет работать после размонтирования? Это тоже правильно? Спасибо!