Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Жизненный цикл в React
Реакт компоненты проходят несколько фаз жизненного цикла. В современном React (с функциональными компонентами) это управляется через Hooks, особенно useEffect.
Фазы жизненного цикла
1. Монтирование (Mounting)
Это процесс создания компонента и вставки его в DOM.
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Фаза монтирования: загружаем данные
console.log("Компонент смонтирован");
const fetchUser = async () => {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
setUser(data);
setLoading(false);
};
fetchUser();
}, []); // Пустой массив зависимостей = выполнить только при монтировании
if (loading) return <div>Загрузка...</div>;
return <div>{user?.name}</div>;
}
Что происходит:
- Компонент создаётся
- Инициализируется состояние (useState)
- Выполняется эффект с пустым массивом зависимостей
- Компонент отрисовывается в DOM
2. Обновление (Updating)
Когда состояние или props изменяются, компонент обновляется.
function SearchResults({ query }) {
const [results, setResults] = useState([]);
useEffect(() => {
// Фаза обновления: выполняется когда query изменяется
console.log(`Поиск по запросу: ${query}`);
const searchUsers = async () => {
const response = await fetch(`/api/search?q=${query}`);
const data = await response.json();
setResults(data);
};
if (query.length > 0) {
searchUsers();
} else {
setResults([]);
}
}, [query]); // Выполнить когда query изменяется
return (
<ul>
{results.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
Особенности:
- Выполняется каждый раз, когда изменяется зависимость
- Может быть несколько useEffect с разными зависимостями
- Позволяет разделить логику по смыслу
3. Размонтирование (Unmounting)
Когда компонент удаляется из DOM.
function WebSocketComponent() {
const [data, setData] = useState(null);
useEffect(() => {
// Монтирование: подключаемся
const ws = new WebSocket("ws://api.example.com/data");
ws.onmessage = (event) => {
setData(event.data);
};
// Размонтирование: очищаем ресурсы
return () => {
console.log("Компонент размонтирован, закрываем соединение");
ws.close();
};
}, []); // Эффект один раз при монтировании
return <div>{data}</div>;
}
Важно:
- Функция, возвращённая из useEffect, это cleanup function
- Она вызывается перед размонтированием или перед повторным выполнением эффекта
- Используется для очистки: закрытие соединений, отписка от событий, отмена таймеров
Полный жизненный цикл
function CompleteLifecycle({ id }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// Эффект 1: Загрузка данных при монтировании
useEffect(() => {
console.log("1. Монтирование: загружаем данные");
setLoading(true);
const loadData = async () => {
try {
const response = await fetch(`/api/data/${id}`);
const result = await response.json();
setData(result);
setError(null);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
loadData();
// Cleanup для монтирования
return () => {
console.log("Очищаем ресурсы при размонтировании");
};
}, []); // Выполнить один раз
// Эффект 2: Реагировать на изменение id
useEffect(() => {
console.log("2. Обновление: id изменился на", id);
// Логика для новых данных
}, [id]); // Выполнить когда id изменяется
// Эффект 3: Логирование каждого обновления
useEffect(() => {
console.log("3. Обновление: данные изменились", data);
}, [data]); // Выполнить когда data изменяется
if (loading) return <div>Загрузка...</div>;
if (error) return <div>Ошибка: {error}</div>;
return <div>{data?.name}</div>;
}
Массив зависимостей (Dependency Array)
| Значение | Когда выполняется |
|---|---|
| Не указан | Каждый раз при обновлении компонента |
[] | Только один раз при монтировании |
[dep1, dep2] | Когда dep1 или dep2 изменяются |
// Без массива зависимостей — выполняется всегда
useEffect(() => {
console.log("Выполняется каждый раз");
});
// Пустой массив — выполняется один раз
useEffect(() => {
console.log("Выполняется при монтировании");
}, []);
// С зависимостями — выполняется при изменении
useEffect(() => {
console.log("Выполняется когда value изменяется");
}, [value]);
Сравнение с классовыми компонентами
В классовых компонентах есть специальные методы жизненного цикла:
class UserProfile extends React.Component {
componentDidMount() {
// Аналог useEffect с []
console.log("Компонент смонтирован");
}
componentDidUpdate(prevProps, prevState) {
// Аналог useEffect без зависимостей
console.log("Компонент обновлён");
}
componentWillUnmount() {
// Аналог cleanup функции
console.log("Компонент размонтирован");
}
render() {
return <div>Содержание</div>;
}
}
Модерный React предпочитает функциональные компоненты с useEffect.
Практические примеры
Пример 1: Таймер с очисткой
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
// Cleanup: остановить таймер
return () => clearInterval(interval);
}, []);
return <div>Прошло {seconds} секунд</div>;
}
Пример 2: Синхронизация с внешним источником
function UserStatus({ userId }) {
const [status, setStatus] = useState("offline");
useEffect(() => {
// Подписываемся на обновления
const unsubscribe = subscribeToUserStatus(userId, (newStatus) => {
setStatus(newStatus);
});
// Cleanup: отписываемся
return () => unsubscribe();
}, [userId]);
return <div>Статус: {status}</div>;
}
Ключевые моменты
- Монтирование — когда компонент появляется в DOM
- Обновление — когда состояние или props изменяются
- Размонтирование — когда компонент удаляется из DOM
- useEffect — основной хук для управления жизненным циклом
- Cleanup функция — важна для избежания утечек памяти
- Массив зависимостей — контролирует когда эффект выполняется
Понимание жизненного цикла критично для написания производительного и надёжного React кода.