Что на самом деле задаёт массив зависимостей useEffect?
Он говорит React, какие значения читает эффект, чтобы эффект перезапускался только при их изменении. Пустой массив означает один запуск после монтирования; отсутствие массива вообще — запуск после каждого рендера, и именно так начинаются бесконечные циклы. Пропустить используемое значение — вторая ошибка: эффект замыкается на устаревшем значении и пользуется им вечно.