useEffect
— это хук (hook) для работы с побочными эффектами (side effects) в функциональных компонентах React. Он объединяет функциональность методов жизненного цикла классовых компонентов: componentDidMount
, componentDidUpdate
и componentWillUnmount
.
import { useEffect } from 'react';
useEffect(() => {
// Код эффекта (effect logic)
return () => {
// Функция очистки (cleanup function)
};
}, [dependencies]); // Массив зависимостей
useEffect(() => {
console.log('Компонент смонтирован');
fetchData(); // Загрузка данных при монтировании
return () => {
console.log('Компонент будет размонтирован');
};
}, []); // Пустой массив зависимостей
useEffect(() => {
document.title = `Новое сообщение: ${message}`;
}, [message]); // Зависимость от message
useEffect(() => {
const timer = setInterval(() => {
console.log('Тик');
}, 1000);
return () => {
clearInterval(timer); // Очистка при размонтировании
};
}, []);
useEffect(() => {
let isMounted = true;
const controller = new AbortController();
async function fetchData() {
try {
const response = await fetch('/api/data', {
signal: controller.signal
});
if (isMounted) {
setData(await response.json());
}
} catch (error) {
if (error.name !== 'AbortError') {
console.error('Ошибка загрузки:', error);
}
}
}
fetchData();
return () => {
isMounted = false;
controller.abort(); // Отмена запроса при размонтировании
};
}, [query]); // Зависит от параметра query
useEffect(() => {
function handleResize() {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
}
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []); // Нет зависимостей - подписка только при монтировании
Массив зависимостей:
[]
— эффект выполняется один раз (при монтировании)[dep1, dep2]
— эффект при изменении dep1 или dep2Порядок выполнения:
Несколько эффектов:
// Можно разделять логику на несколько useEffect
useEffect(() => { /* логика 1 */ }, [dep1]);
useEffect(() => { /* логика 2 */ }, [dep2]);
Забывают про очистку:
// Плохо: утечка памяти
useEffect(() => {
setInterval(() => {}, 1000);
}, []);
// Хорошо:
useEffect(() => {
const id = setInterval(() => {}, 1000);
return () => clearInterval(id);
}, []);
Неправильные зависимости:
// Пропущена зависимость
useEffect(() => {
fetchUser(userId);
}, []); // Должно быть [userId]
Бесконечные циклы:
// Бесконечный рендеринг
useEffect(() => {
setCount(count + 1);
}, [count]); // Эффект изменяет свою зависимость
Мемоизация колбэков:
const fetchData = useCallback(() => {
// логика запроса
}, [query]);
useEffect(() => {
fetchData();
}, [fetchData]);
Разделение эффектов:
// Разделение несвязанной логики
useEffect(() => { /* логика A */ }, [depA]);
useEffect(() => { /* логика B */ }, [depB]);
useEffect
— это мощный инструмент для работы с побочными эффектами в функциональных компонентах React. Он заменяет методы жизненного цикла классовых компонентов, предлагая более гибкий и понятный способ управления side effects. Правильное использование useEffect
требует понимания его работы с зависимостями, важности очистки эффектов и особенностей выполнения. Этот хук является фундаментальным для современных React-приложений и его грамотное применение критически важно для создания надежных и эффективных компонентов.