Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: React, useEffect, dependencies, eslint-plugin-react-hooks, closure

Почему линтер может ругаться на пустой массив зависимостей в useEffect, даже если это намеренно?

Проверяет понимание правил хуков React и необходимости указания всех зависимостей в useEffect для избежания багов с устаревшими замыканиями.

Короткий ответ

Линтер (eslint-plugin-react-hooks) требует указывать все переменные и функции, используемые внутри useEffect, в массиве зависимостей. Пустой массив означает, что эффект выполняется только один раз при монтировании. Если внутри эффекта используются пропсы, стейт или другие значения, они могут быть устаревшими (stale closure). Линтер предупреждает об этом, чтобы предотвратить баги. Если пустой массив намеренный, нужно либо вынести логику в useRef, либо добавить комментарий // eslint-disable-next-line.

Длинный ответ

Почему линтер ругается на пустой массив зависимостей в useEffect?

Линтер, а именно плагин eslint-plugin-react-hooks, анализирует код на соответствие правилам хуков React. Одно из ключевых правил — react-hooks/exhaustive-deps. Оно требует, чтобы все переменные, функции и пропсы, используемые внутри useEffect, были перечислены в массиве зависимостей. Если массив пуст, а внутри эффекта есть обращения к внешним значениям, линтер выдаёт предупреждение или ошибку.

Проблема устаревших замыканий

Когда вы передаёте пустой массив [], эффект выполняется только один раз — при монтировании компонента. Все переменные, захваченные в замыкание эффекта, сохраняют свои значения на момент первого рендера. Если эти переменные позже изменятся (например, через useState или пропсы), эффект продолжит использовать старые значения. Это называется stale closure (устаревшее замыкание).

Пример проблемы

function Timer({ start }) {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(count + 1); // count всегда 0, так как захвачен при монтировании
    }, 1000);
    return () => clearInterval(id);
  }, []); // линтер ругается: count не указан в зависимостях

  return <div>{count}</div>;
}

В этом примере count внутри setInterval всегда будет равен 0, потому что эффект захватил его при первом рендере. Линтер предупреждает, что count должен быть в зависимостях.

Когда пустой массив намеренный

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

  • Использовать useRef для хранения актуальных значений, чтобы избежать устаревших замыканий.
  • Добавить комментарий // eslint-disable-next-line react-hooks/exhaustive-deps над строкой с массивом, чтобы отключить предупреждение.

Правильный подход

function Timer({ start }) {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(prev => prev + 1); // используем функциональную форму setState
    }, 1000);
    return () => clearInterval(id);
  }, []); // теперь линтер не ругается, так как нет внешних зависимостей

  return <div>{count}</div>;
}

В этом варианте мы используем функциональную форму setCount, которая не зависит от внешнего count. Линтер видит, что внутри эффекта нет обращений к переменным из рендера, поэтому пустой массив допустим.

Вывод

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

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

  • React

    React

Ключевые слова

#React

#useEffect

#dependencies

#eslint-plugin-react-hooks

#closure

Подпишись на React Developer в телеграм

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию