Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Вызов useEffect один раз при монтировании компонента
useEffect — это React хук, который позволяет выполнять побочные эффекты (side effects) в функциональных компонентах. Часто требуется выполнить код один раз при монтировании компонента, например для загрузки данных с сервера.
Использование пустого массива зависимостей
Чтобы вызвать useEffect только один раз при монтировании компонента, нужно передать пустой массив зависимостей []:
import { useEffect, useState } from 'react';
function MyComponent() {
const [data, setData] = useState(null);
useEffect(() => {
console.log('Компонент смонтирован!');
// Код выполнится один раз
}, []);
return <div>{data}</div>;
}
Как это работает?
Hook useEffect имеет параметр — массив зависимостей (dependency array). React сравнивает зависимости перед каждым рендером:
- Без массива зависимостей: эффект выполняется после каждого рендера
- Пустой массив
[]: эффект выполняется один раз после первого рендера - С зависимостями
[dep1, dep2]: эффект выполняется, когда любая из зависимостей изменилась
// ❌ Выполнится при каждом рендере
useEffect(() => {
console.log('После каждого рендера');
});
// ✅ Выполнится один раз при монтировании
useEffect(() => {
console.log('При монтировании');
}, []);
// Выполнится при изменении userId
useEffect(() => {
console.log('userId изменился:', userId);
}, [userId]);
Практический пример: загрузка данных
import { useEffect, useState } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchUser() {
try {
setLoading(true);
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
setUser(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchUser();
}, []); // Зависит от пустого массива — загружается один раз при монтировании
if (loading) return <div>Загрузка...</div>;
if (error) return <div>Ошибка: {error}</div>;
return <div>{user.name}</div>;
}
Очистка ресурсов (Cleanup function)
При размонтировании компонента часто требуется очистить ресурсы. Это делается через return функцию внутри useEffect:
useEffect(() => {
console.log('Компонент смонтирован');
// Cleanup функция — выполнится при размонтировании
return () => {
console.log('Компонент размонтирован');
// Отписка от событий, отмена запросов, очистка памяти
};
}, []);
Пример с подпиской на события
function WindowResize() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
// Cleanup: отписаться при размонтировании
return () => {
window.removeEventListener('resize', handleResize);
};
}, []); // Один раз при монтировании
return <div>Ширина: {width}px</div>;
}
Частая ошибка: зависит от userId
function UserProfile({ userId }) {
useEffect(() => {
// Если userId изменится, нужно перезагрузить данные
fetchUser(userId);
}, [userId]); // Добавляем userId в зависимости!
}
Сравнение подходов
| Массив | Когда выполняется | Использование |
|---|---|---|
| Не указан | После каждого рендера | Редко |
[] | Один раз при монтировании | Инициализация, загрузка данных |
[dep1, dep2] | Когда изменился dep1 или dep2 | Реактивные эффекты |
Резюме
Чтобы вызвать useEffect один раз при монтировании компонента, передайте пустой массив зависимостей []. Это основной паттерн для выполнения инициализационного кода, загрузки начальных данных с сервера и настройки подписок на события. Не забудьте про cleanup функцию, если нужно освобождать ресурсы при размонтировании.