← Назад к вопросам

Какие этапы жизненного цикла в React приложении знаешь?

2.0 Middle🔥 291 комментариев
#React#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Жизненный цикл React-компонента: от создания до удаления

Жизненный цикл React-компонента — это последовательность методов, которые вызываются на разных этапах существования компонента. Эти этапы можно разделить на три основные фазы: монтирование (mounting), обновление (updating) и размонтирование (unmounting). После выхода React 16.8 с хуками появился также этап работы с эффектами, который дополняет традиционный жизненный цикл.

Традиционный подход (классовые компоненты)

1. Фаза монтирования (Mounting)

Компонент создается и вставляется в DOM.

  • constructor() — инициализация состояния и привязка методов:
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
    this.handleClick = this.handleClick.bind(this);
  }
}
  • static getDerivedStateFromProps() — синхронизация состояния с пропсами (редко используется):
static getDerivedStateFromProps(props, state) {
  if (props.value !== state.prevValue) {
    return { value: props.value, prevValue: props.value };
  }
  return null;
}
  • render() — обязательный метод, возвращает JSX:
render() {
  return <div>Count: {this.state.count}</div>;
}
  • componentDidMount() — компонент смонтирован, можно выполнять сайд-эффекты:
componentDidMount() {
  this.timerID = setInterval(() => this.tick(), 1000);
  // Запросы к API, подписки на события
}

2. Фаза обновления (Updating)

Вызывается при изменении пропсов или состояния.

  • shouldComponentUpdate() — оптимизация производительности (возвращает boolean):
shouldComponentUpdate(nextProps, nextState) {
  return nextState.count !== this.state.count;
}
  • render() — перерисовка компонента с новыми данными.

  • getSnapshotBeforeUpdate() — захват информации DOM перед обновлением:

getSnapshotBeforeUpdate(prevProps, prevState) {
  if (prevProps.items.length < this.props.items.length) {
    return this.listRef.scrollHeight;
  }
  return null;
}
  • componentDidUpdate() — обновление завершено, можно работать с DOM:
componentDidUpdate(prevProps, prevState, snapshot) {
  if (snapshot !== null) {
    this.listRef.scrollTop = this.listRef.scrollHeight - snapshot;
  }
}

3. Фаза размонтирования (Unmounting)

Удаление компонента из DOM.

  • componentWillUnmount() — очистка ресурсов:
componentWillUnmount() {
  clearInterval(this.timerID);
  // Отмена подписок, таймеров, сетевых запросов
}

Современный подход (функциональные компоненты с хуками)

С появлением хуков жизненный цикл стал более декларативным:

1. Монтирование и обновление через useEffect

import { useState, useEffect } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);
  
  // Аналог componentDidMount + componentDidUpdate
  useEffect(() => {
    console.log('Компонент смонтирован или обновлен');
    return () => {
      console.log('Очистка перед следующим эффектом или размонтированием');
    };
  });

  // Только при монтировании (пустой массив зависимостей)
  useEffect(() => {
    console.log('Только при монтировании');
  }, []);

  // Только при изменении count
  useEffect(() => {
    console.log('Count изменился:', count);
  }, [count]);
  
  // Аналог componentWillUnmount
  useEffect(() => {
    return () => {
      console.log('Компонент будет размонтирован');
    };
  }, []);
}

2. Дополнительные возможности

  • useLayoutEffect — синхронный аналог useEffect, выполняется перед отрисовкой DOM
  • useMemo и useCallback — оптимизация ререндеров (аналог shouldComponentUpdate)
  • Ключевые отличия хуков от классового подхода:
    • Нет методов жизненного цикла как таковых, есть эффекты
    • Эффекты объединяют логику, а не разделяют её по разным методам
    • Очистка эффектов описывается в одном месте (return-функция)

Ошибки и их обработка

С React 16 появилась фаза обработки ошибок:

  • static getDerivedStateFromError() — обновление состояния при ошибке
  • componentDidCatch() — логирование ошибок (только классовые компоненты)
  • Error Boundaries — компоненты-перехватчики ошибок в дочерних компонентах

Практические рекомендации

Наиболее важные этапы для повседневной разработки:

  1. Инициализация — constructor (классы) или useState (хуки)
  2. Сайд-эффекты при монтировании — componentDidMount или useEffect с []
  3. Обработка обновлений — componentDidUpdate или useEffect с зависимостями
  4. Очистка ресурсов — componentWillUnmount или return-функция в useEffect
  5. Оптимизация ререндеров — shouldComponentUpdate или useMemo/useCallback

Современная практика склоняется к использованию функциональных компонентов с хуками, так как они предлагают более предсказуемую и композируемую модель жизненного цикла через эффекты. Однако понимание классового подхода остается важным для работы с легаси-кодом и глубокого понимания работы React.