web-dev-qa-db-fra.com

Impossible de supprimer un écouteur d'événements en dehors de useEffect

J'ajoute un écouteur d'événements dans useEffect. Il s'exécute une fois après le premier rendu en raison du seEffect second argument ([]). Ensuite, j'essaie de le supprimer en dehors de useEffect (dans la fonction handleSearch) mais cela ne fonctionne pas. Je soupçonne que cela a quelque chose à voir avec les étendues de fonction, mais je ne le comprends pas complètement. Il existe peut-être une solution de contournement?

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);
  };
}, []);
8
Andrew Lukjanov

La raison pour laquelle cela ne fonctionne pas est parce que setPageHeightWrapper est défini comme une fonction inline et lorsque le composant en rend une nouvelle instance est créée et tout en effaçant un écouteur d'événements, vous devez passer la même méthode qui a été passée tout en définissant l'auditeur.

D'un autre côté, lorsqu'un hook useEffect est appelé, il obtient la référence de fonction à partir de sa fermeture et il utilise la même référence pour effacer l'écouteur.

Un moyen de faire fonctionner removeListener en dehors de useEffect est d'utiliser 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);
  };
}, []);
9
Shubham Khatri