Отсутствует ошибка подстановки зависимостей на React hook - PullRequest
1 голос
/ 02 мая 2020

Я использую useEffect в компоненте функции React следующим образом:

useEffect(() => {
  const handleRouteChangeComplete = () => {
    window.scrollTo(0, 0);
    userInterface.dispatch(closeNavigation());
  };

  Router.events.on('routeChangeComplete', handleRouteChangeComplete);
}, []);

Второй параметр (массив) в useEffect дает мне следующую ошибку linting:

React Hook useEffect has a missing dependency: 'userInterface'. Either include it or remove the dependency array. eslint(react-hooks/exhaustive-deps)

Я не думаю, что какой-либо из параметров в ошибке linting верен.

  • Я хочу инициализировать прослушиватель только один раз.
  • Если я удалю параметр массива , useEffect будет вести себя как componentDidUpdate и может выполнять код более одного раза
  • Если я добавлю userInterface в качестве зависимости от useEffect, он также выполнит код более одного раза, если этот контекст обновления

Я что-то здесь упускаю или что-то заставляет меня писать неправильные логи c?

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

1 Ответ

2 голосов
/ 02 мая 2020

Существует причина ошибки eslint, которая заключается в том, чтобы не допустить заметных ошибок из-за устаревших значений. По сути, ошибка lint просто говорит вам, что ваша переменная userInterface будет устаревшей в пределах эффекта.

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

Еще один пост о том же:

useEffect массив зависимостей и правило исчерпывающего действия ESLint

https://github.com/facebook/create-react-app/issues/6880

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

У вас есть несколько разных способов, как это исправить, если диспетчеризация стабильна (которая, как правило, основана на названии, то), то вы можете извлечь отправление от переменной userInterface и затем добавление ее в массив зависимостей.

const { dispatch } = userInterface;

useEffect(() => {
  const handleRouteChangeComplete = () => {
    window.scrollTo(0, 0);
    dispatch(closeNavigation());
  };

  Router.events.on('routeChangeComplete', handleRouteChangeComplete);
  () => {
    Router.events.off('routeChangeComplete', handleRouteChangeComplete);
  };
}, [dispatch]);

Если выгрузить значение отправки не вариант, n вы можете использовать ссылку, чтобы убедиться, что последняя версия userInterface поддерживается стабильно. Иногда это достаточно распространенная задача, и вы можете захотеть извлечь logi c в пользовательский хук, чтобы получить ссылку на значение.

const userInterfaceRef = useRef(userInterface);
useEffect(() => {
  userInterfaceRef.current = userInterface;
}, [userInterface]);

useEffect(() => {
  const handleRouteChangeComplete = () => {
    window.scrollTo(0, 0);
    userInterfaceRef.current.dispatch(closeNavigation());
  };

  Router.events.on('routeChangeComplete', handleRouteChangeComplete);
  () => {
    Router.events.off('routeChangeComplete', handleRouteChangeComplete);
  };
}, []);

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

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

Если вы добавляете обработчик на что-то обязательно в эффекте, вы должны обязательно очистить его. Это хорошая привычка.

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