В мире React каждый компонент проходит три этапа: монтирование, обновление и размонтирование. Этот процесс называют жизненным циклом компонентов. Понимание того, что происходит на каждом этапе, поможет вам создавать более эффективные и удобные приложения.

Сегодня мы разберём основы жизненного цикла, познакомимся с хуком useEffect и создадим простой таймер, который обновляет текущее время каждую секунду.

Основы жизненного цикла компонентов

Каждый компонент React проходит три основные стадии:

  1. Монтирование (Mounting): Это момент, когда компонент появляется в DOM. Пример: пользователь открывает приложение, и компонент рендерится на экране.
  2. Обновление (Updating): Стадия, когда состояние (state) или пропсы (props) компонента изменяются, и он заново рендерится. Пример: пользователь нажал кнопку, и компонент обновился.
  3. Размонтирование (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

Без регистрации и смс