Как использовать React useCallback и useEffect с внешними зависимостями - PullRequest
0 голосов
/ 06 ноября 2019

Я пытаюсь следить за реакцией-плагином-реакцией-хуками.

У меня есть useEffect, который добавляет прослушиватель событий к window (onScroll). onScroll использует window.pageYOffset.

function onScroll() {
    if (window.pageYOffset > 0) {
      setFoor(bar)
    } else {
      setFoor(baz)
    }
  }

Теперь в useEffect у меня есть:

useEffect(() => {
    window.addEventListener('scroll', onScroll);
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
    };
  }, []);

Это следовало рекомендации изначально поддерживаемой идеи, что если вы передадитепустой массив зависимостей, это как componentDidMount. Но в документах React четко сказано, что вы не должны передавать ни зависимости (даже пустой массив), ни все зависимости (которые относятся к реквизитам или состоянию). (https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) Так это будет выглядеть так:

useEffect(() => {
    window.addEventListener('scroll', onScroll);
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
    };
  }, [onsScroll]);

Но это означает, что я должен использовать useCallback для onScroll, иначе у него всегда будет другая зависимость. Но useCallback«Зависимость» для onScroll будет window.pageYOffset, но это не сработает, то есть:

function onScroll = React.useCallback(() => {
    if (window.pageYOffset > 0) {
      setFoor(bar)
    } else {
      setFoor(baz)
    }
  }, [window.pageYOffset])

Мой общий вопрос: как вы справляетесь с useEffect / useCallback функциями, которыебыли внешние зависимости? (Кроме того, игнорируйте предупреждение.)

Спасибо

Я также пытался полностью переместить определение onScroll в useEffect, но оно не обновляется должным образом.

useEffect(() => {
    function onScroll() {
      if (window.pageYOffset > 0 && !slim) {
        setSlim(true);
      } else {
        setSlim(false);
      }
    }
    window.addEventListener('scroll', onScroll, onScrollOptions);
    onScroll();
    getAccountAction();
    return () => {
      window.removeEventListener('scroll', onScroll, onScrollOptions);
    };
  }, []);

Ответы [ 2 ]

0 голосов
/ 06 ноября 2019

Даже если вы определяете обработчик прокрутки внутри useEffect, вы по-прежнему получаете доступ к смещению извне, которое необходимо отслеживать внутри массива зависимостей, а также состояния slim var.

Ваша функция onScroll может быть упрощена с помощью функциональной формы setState, в этом случае вам больше не нужно отслеживать slim переменную состояния:

useEffect(() => {
  function onScroll() {
    setSlim(currentSlim => window.pageYOffset > 0 && !currentSlim)
  }

  window.addEventListener('scroll', onScroll, onScrollOptions);
  getAccountAction();
  return () => {
    window.removeEventListener('scroll', onScroll, onScrollOptions);
  };
}, [window.pageYOffset]);
0 голосов
/ 06 ноября 2019

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

В обработчике событий я бы изменил состояние, установив значение pageoffset и другой эффектиспользовать это состояние в качестве зависимости

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...