В мире React каждый компонент проходит три этапа: монтирование, обновление и размонтирование. Этот процесс называют жизненным циклом компонентов. Понимание того, что происходит на каждом этапе, поможет вам создавать более эффективные и удобные приложения.
Сегодня мы разберём основы жизненного цикла, познакомимся с хуком useEffect и создадим простой таймер, который обновляет текущее время каждую секунду.
Основы жизненного цикла компонентов
Каждый компонент React проходит три основные стадии:
- Монтирование (Mounting): Это момент, когда компонент появляется в DOM. Пример: пользователь открывает приложение, и компонент рендерится на экране.
- Обновление (Updating): Стадия, когда состояние (state) или пропсы (props) компонента изменяются, и он заново рендерится. Пример: пользователь нажал кнопку, и компонент обновился.
- Размонтирование (Unmounting): Это когда компонент удаляется из DOM. Пример: пользователь переключился на другую страницу, и компонент больше не нужен.
Как хуки изменили подход к жизненному циклу
Раньше для работы с жизненным циклом в классовых компонентах использовались методы, такие как:
- componentDidMount (монтирование),
- componentDidUpdate (обновление),
- componentWillUnmount (размонтирование).
Это было мощно, но сложно. Код быстро разрастался, и обработка разных этапов жизни компонента становилась путаницей.
С появлением хуков, таких как useEffect, управление жизненным циклом стало проще и удобнее.
Что такое useEffect?
useEffect — это хук, который позволяет управлять побочными эффектами (например, загрузка данных, подписки, таймеры) в функциональных компонентах. Он объединяет функциональность componentDidMount, componentDidUpdate и componentWillUnmount в одну удобную функцию.
Синтаксис
useEffect(() => {
// Код, выполняющийся после рендера
return () => {
// Код для очистки (опционально)
};
}, [dependencies]);
Что здесь происходит?
- Основная функция выполняется после рендера компонента.
- Функция очистки (return () => {}) вызывается перед следующим вызовом эффекта или при размонтировании компонента.
- Массив зависимостей ([dependencies]) определяет, когда эффект должен выполняться.
Базовые паттерны использования useEffect
Эффект без зависимостей
Если вы не укажете массив зависимостей, эффект будет выполняться при каждом рендере:
useEffect(() => {
console.log('Компонент перерендерился');
});
Эффект с пустым массивом
Укажите пустой массив зависимостей, если хотите, чтобы эффект выполнялся только при монтировании:
useEffect(() => {
console.log('Компонент смонтирован');
}, []);
Эффект с зависимостями
Укажите зависимости, чтобы эффект выполнялся только при их изменении:
useEffect(() => {
console.log('Зависимость изменилась');
}, [dependency]);
Очистка эффекта
Если ваш эффект создаёт подписку или таймер, обязательно очищайте их:
useEffect(() => {
const timer = setInterval(() => console.log('Таймер работает'), 1000);
return () => {
clearInterval(timer); // Очистка при размонтировании
};
}, []);
Практика: создаём таймер
Давайте применим наши знания и создадим компонент, который обновляет текущее время каждую секунду.
Задача
- Отображать текущее время.
- Обновлять время каждую секунду.
- Очистить таймер при размонтировании компонента.
Шаг 1: Создаём компонент Clock
Откройте файл App.jsx и добавьте следующий код:
import React, { useState, useEffect } from 'react';
function Clock() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
// Создаём таймер, который обновляет время каждую секунду
const timer = setInterval(() => {
setTime(new Date().toLocaleTimeString());
}, 1000);
// Очистка таймера при размонтировании
return () => {
clearInterval(timer);
};
}, []); // Пустой массив зависимостей: эффект выполняется только при монтировании
return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>Текущее время</h1>
<p style={{ fontSize: '2rem', fontWeight: 'bold' }}>{time}</p>
</div>
);
}
function App() {
return <Clock />;
}
export default App;
Разбираем код
useState для хранения времени
Мы используем useState для хранения текущего времени. Начальное значение — результат вызова new Date().toLocaleTimeString().
useEffect для обновления времени
Таймер запускается при монтировании компонента и вызывает setTime каждую секунду.
clearInterval удаляет таймер, чтобы предотвратить утечку памяти, когда компонент размонтируется.
Пустой массив зависимостей
Таймер создаётся только один раз, при первом рендере компонента.
Шаг 2: Запускаем приложение
Запустите приложение:
npm run dev
Откройте приложение в браузере. Вы увидите текущее время, которое обновляется каждую секунду.
Дополнительное задание: стилизуем таймер
Добавьте стили, чтобы сделать таймер красивее. Например:
function Clock() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
const timer = setInterval(() => {
setTime(new Date().toLocaleTimeString());
}, 1000);
return () => clearInterval(timer);
}, []);
return (
<div style={{
textAlign: 'center',
marginTop: '50px',
fontFamily: 'Arial, sans-serif',
}}>
<h1 style={{ color: '#007BFF', fontSize: '2.5rem' }}>Текущее время</h1>
<p style={{
fontSize: '3rem',
fontWeight: 'bold',
color: '#333',
background: '#f0f0f0',
display: 'inline-block',
padding: '10px 20px',
borderRadius: '8px',
}}>
{time}
</p>
</div>
);
}
Теперь таймер выглядит более профессионально!
Итоги
Сегодня мы разобрали:
- Жизненный цикл компонентов — монтирование, обновление и размонтирование.
- Хук useEffect — универсальный инструмент для управления побочными эффектами.
- Как создавать и очищать эффекты, используя зависимости и функции очистки.
На практике мы создали компонент таймера, который обновляет текущее время каждую секунду и корректно очищает таймер при размонтировании.
Теперь вы готовы к созданию более сложных компонентов, которые взаимодействуют с внешними API, подписками или анимациями.
Комментарии
0