Для чего служит второй аргумент у useEffect в React
Что проверяют
Понимаете ли вы, что массив зависимостей это не настройка частоты, а список значений, от которых эффект зависит. Заодно проверяют, знаете ли вы про сравнение по ссылке.
Как отвечать
Второй аргумент это массив зависимостей: React сравнивает его с предыдущим рендером и перезапускает эффект, только если что-то изменилось.
Три варианта поведения:
- массив не указан: эффект выполняется после каждого рендера;
- пустой массив: один раз после монтирования, очистка при размонтировании;
- массив со значениями: после монтирования и каждый раз, когда любое значение изменилось.
Ключевые детали, которые и хотят услышать:
- сравнение поверхностное, по ссылке (
Object.is). Объект, массив или функция, созданные в теле компонента, каждый рендер новые, поэтому эффект будет запускаться бесконечно. Лечится переносом значения наружу,useMemo,useCallbackили указанием в зависимостях примитивов вместо объекта; - в зависимости попадает всё, что эффект использует: пропсы, состояние, функции. Умалчивать нельзя, иначе эффект работает со старыми значениями, и это самый частый источник трудноуловимых ошибок. Правило линтера
exhaustive-depsсуществует именно для этого; - функция очистки возвращается из эффекта и вызывается перед следующим запуском и при размонтировании: отписки, таймеры, отмена запросов;
- в строгом режиме разработки эффект намеренно запускается дважды, чтобы обнаружить незакрытые подписки.
Полезно добавить: если эффект нужен только для вычисления значения из пропсов, он обычно не нужен вовсе, значение считают прямо при рендере.
Где спотыкаются
Указывают пустой массив, чтобы «выполнилось один раз», и эффект замыкает устаревшее состояние.
Кладут в зависимости объект и получают бесконечный цикл.
Загружают данные в эффекте без отмены, и ответ приходит после ухода со страницы.