← Назад к вопросам

Что если передать массив в useEffect?

2.0 Middle🔥 191 комментариев
#React

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что если передать массив в useEffect

Это очень частая ошибка, которая приводит к бесконечным циклам эффектов. Давайте разберёмся, что происходит и почему это проблема.

Проблема: массив в dependencies

Когда вы передаёте массив в массив зависимостей useEffect, React сравнивает его по ссылке, а не по содержимому:

const myArray = [1, 2, 3];

function MyComponent() {
  useEffect(() => {
    console.log("Effect ran");
    fetchData(myArray);
  }, [myArray]); // ПРОБЛЕМА!
}

Этот код будет вызывать effect бесконечно. Почему?

Почему это происходит

React сравнивает зависимости по ссылке (===), а не по значению:

const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];

console.log(arr1 === arr2); // false! Разные ссылки
console.log(arr1[0] === arr2[0]); // true, но это не важно

Цикл:

  1. Компонент рендерится
  2. Создаётся новый массив
  3. useEffect видит, что массив в зависимостях изменился
  4. Effect запускается
  5. Effect вызывает setState
  6. Компонент рендерится заново
  7. Создаётся новый массив... и снова в шаг 3

Реальный пример с бесконечным циклом

function UsersList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const userIds = [1, 2, 3];
    
    setLoading(true);
    fetchUsers(userIds).then(data => {
      setUsers(data);
      setLoading(false);
    });
  }, [userIds]);
}

Решение 1: Положить массив вне компонента

const USER_IDS = [1, 2, 3];

function UsersList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    setLoading(true);
    fetchUsers(USER_IDS).then(data => {
      setUsers(data);
    });
  }, [USER_IDS]);
}

Решение 2: Использовать useMemo

Если массив зависит от state/props, используй useMemo для стабильной ссылки:

function UsersList({ ids }) {
  const [users, setUsers] = useState([]);

  const stableIds = useMemo(() => ids, [ids]);

  useEffect(() => {
    fetchUsers(stableIds).then(setUsers);
  }, [stableIds]);
}

Решение 3: Не передавайте массив в зависимости

Если массив не критичен, просто не передавайте его:

const USER_IDS = [1, 2, 3];

function UsersList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetchUsers(USER_IDS).then(setUsers);
  }, []);
}

Проверка: как избежать ошибки

Правило простое:

  • Если вы видите warning "missing dependencies" — НЕ просто добавляйте переменную
  • Сначала спросите: почему эта переменная меняется?
  • Если это массив в useMemo, то он стабилен
  • Если это обычный массив из state — нужна стабилизация

Итог

  • Массив в dependencies = новая ссылка при каждом рендере
  • Это может привести к бесконечному циклу
  • Решение: useMemo, вынести вне компонента или пересмотреть логику
  • Обычно массивы вообще не нужны в зависимостях