Невозможно удалить прослушиватель событий вне useEffect - PullRequest
0 голосов
/ 07 февраля 2019

Я добавляю прослушиватель событий внутрь useEffect.Он запускается один раз после первого рендеринга из-за второго аргумента useEffect ([]) .Затем я пытаюсь удалить его за пределами useEffect (в функции handleSearch), но это не работает.Я подозреваю, что это как-то связано с областями функций, но я не до конца понимаю.Может быть, есть обходной путь?

const handleSearch = () => {
  window.removeEventListener('resize', setPageHeightWrapper);
};

const [pageHeight, setPageHeight] = useState(0);

function setPageHeightWrapper() { setPageHeight(window.innerHeight); };
useEffect(() =>{
  window.addEventListener('resize', setPageHeightWrapper);
  return () => {
    window.removeEventListener('resize', setPageHeightWrapper);
  };
}, []);

1 Ответ

0 голосов
/ 07 февраля 2019

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

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

A wayчтобы заставить removeListener работать за пределами useEffect - использовать useCallback hook

const handleSearch = () => {
  window.removeEventListener('resize', memoHeightWrapper);
};

const [pageHeight, setPageHeight] = useState(0);


const memoHeightWrapper = useCallback(() => {
    setPageHeight(window.innerHeight);
})
useEffect(() =>{
  window.addEventListener('resize', memoHeightWrapper);
  return () => {
    window.removeEventListener('resize', memoHeightWrapper);
  };
}, []);
...