Как правильно указывать зависимости в useEffect в React
Что проверяют
Понимаете ли вы, что зависимости это не настройка частоты запуска, а список того, что эффект использует.
Как отвечать
Правило одно: в массиве должно быть всё, что эффект читает из области компонента, то есть пропсы, состояние и функции. Линтер react-hooks/exhaustive-deps проверяет это, и его подавление комментарием почти всегда означает ошибку в проектировании, а не ложное срабатывание.
Что делать, когда зависимостей слишком много:
- перенести объявление внутрь эффекта: функция, которая нужна только ему, объявляется прямо там и из зависимостей исчезает;
- обернуть функцию в
useCallback, если она приходит извне и передаётся дальше; - использовать функциональное обновление:
setCount(c => c + 1)вместоsetCount(count + 1)убираетcountиз зависимостей; - вынести объект или массив из тела компонента, потому что литерал создаётся заново на каждый рендер и делает зависимость всегда новой;
useRefдля значений, которые эффект должен видеть свежими, но не должен на них перезапускаться, либоuseEffectEventв новых версиях.
Пустой массив означает «эффект не зависит ни от чего» и уместен только тогда, когда это правда: подписка на глобальное событие, разовая инициализация.
Главная мысль, которую стоит произнести: если убрать зависимость хочется ради того, чтобы эффект не перезапускался, значит проблема в самом эффекте, а не в списке. Обычно он делает две разные вещи и его надо разделить.
Где спотыкаются
Отключают линтер комментарием и получают устаревшее замыкание.
Кладут в зависимости объект-литерал и получают бесконечный цикл.
Ставят пустой массив, чтобы «не мигало».
Считают массив зависимостей аналогом методов жизненного цикла.