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

Что такое стадия жизненного цикла классового компонента?

1.0 Junior🔥 131 комментариев
#React

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

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

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

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

Жизненный цикл — это последовательность этапов, через которые проходит компонент от создания до удаления из DOM. В классовых компонентах есть специальные методы для реагирования на эти события.

Три стадии жизненного цикла

1. Монтирование (Mounting)

Этап создания компонента и добавления в DOM:

class Component extends React.Component {
  constructor(props) {
    super(props);
    console.log('1. Конструктор');
    this.state = { count: 0 };
  }
  
  componentDidMount() {
    console.log('4. Монтирование завершено');
    // Здесь: API запросы, подписки, таймеры
  }
  
  render() {
    console.log('3. Рендеринг');
    return <div>{this.state.count}</div>;
  }
  
  // getDerivedStateFromProps (редко используется)
  static getDerivedStateFromProps(props, state) {
    console.log('2. Получить состояние из пропсов');
    return null;  // или новое состояние
  }
}

// Порядок при монтировании:
// 1. Конструктор
// 2. Получить состояние из пропсов (если есть)
// 3. Рендеринг
// 4. Монтирование завершено

2. Обновление (Updating)

Этап при изменении пропсов или состояния:

class Component extends React.Component {
  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log('После обновления');
    // Сравнить prevProps/prevState с текущими
    if (prevProps.id !== this.props.id) {
      // Пропсы изменились
      this.loadData(this.props.id);
    }
  }
  
  shouldComponentUpdate(nextProps, nextState) {
    console.log('Нужно ли обновлять?');
    // Вернуть true (обновить) или false (пропустить)
    return nextProps.value !== this.props.value;
  }
  
  getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log('Перед обновлением DOM');
    // Сохранить информацию перед обновлением
    return { scrollPosition: window.scrollY };
  }
  
  render() {
    return <div>{this.props.value}</div>;
  }
}

// Порядок при обновлении:
// 1. shouldComponentUpdate (решить обновлять ли)
// 2. getDerivedStateFromProps
// 3. Рендеринг
// 4. getSnapshotBeforeUpdate (перед обновлением DOM)
// 5. componentDidUpdate (после обновления)

3. Размонтирование (Unmounting)

Этап удаления компонента из DOM:

class Component extends React.Component {
  componentWillUnmount() {
    console.log('Компонент удаляется');
    // Очистить: таймеры, подписки, обработчики
    clearInterval(this.timer);
    this.socket.disconnect();
  }
  
  render() {
    return <div>Будет удален</div>;
  }
}

Практические примеры

API запрос в componentDidMount

class UserProfile extends React.Component {
  constructor(props) {
    super(props);
    this.state = { user: null, loading: true };
  }
  
  componentDidMount() {
    // Загрузить данные
    fetch(`/api/users/${this.props.userId}`)
      .then(r => r.json())
      .then(user => {
        this.setState({ user, loading: false });
      })
      .catch(err => {
        this.setState({ error: err, loading: false });
      });
  }
  
  render() {
    if (this.state.loading) return <div>Загрузка...</div>;
    return <div>{this.state.user.name}</div>;
  }
}

Отслеживание изменения пропсов

class Component extends React.Component {
  componentDidUpdate(prevProps) {
    // Если userId изменился
    if (prevProps.userId !== this.props.userId) {
      this.loadUserData(this.props.userId);
    }
  }
  
  loadUserData(userId) {
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(data => this.setState({ data }));
  }
  
  render() {
    return <div>{this.state.data?.name}</div>;
  }
}

Очистка подписок

class Chat extends React.Component {
  componentDidMount() {
    // Подписаться на обновления
    this.unsubscribe = store.subscribe(() => {
      this.forceUpdate();
    });
  }
  
  componentWillUnmount() {
    // Отписаться (важно!)
    this.unsubscribe();
  }
  
  render() {
    return <div>{store.getState().messages}</div>;
  }
}

shouldComponentUpdate оптимизация

class Item extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    // Обновить только если name или id изменились
    return (
      nextProps.name !== this.props.name ||
      nextProps.id !== this.props.id
    );
  }
  
  render() {
    return <li>{this.props.name}</li>;
  }
}

Диаграмма жизненного цикла

МОНТИРОВАНИЕ:
constructor → getDerivedStateFromProps → render → componentDidMount

ОБНОВЛЕНИЕ (пропсы или state):
shouldComponentUpdate → getDerivedStateFromProps → render → 
getSnapshotBeforeUpdate → componentDidUpdate

РАЗМОНТИРОВАНИЕ:
componentWillUnmount

ОШИБКА:
componentDidCatch (для обработки ошибок)

Устаревшие методы

В React 16.3+ небезопасны:

// ❌ НЕ используй:
componentWillMount()      // Используй constructor или componentDidMount
componentWillReceiveProps() // Используй componentDidUpdate
componentWillUpdate()     // Используй componentDidUpdate

Функциональные компоненты вместо классовых

В современном React функциональные компоненты с хуками предпочтительнее:

// Вместо componentDidMount
useEffect(() => {
  loadData();
  return () => cleanup();  // Вместо componentWillUnmount
}, []);

// Вместо componentDidUpdate
useEffect(() => {
  loadData();
}, [dependencies]);

// Вместо shouldComponentUpdate
const Component = React.memo(({ id }) => { ... });

Правила и рекомендации

  1. componentDidMount:

    • API запросы
    • Подписки
    • DOM манипуляции
    • Таймеры/интервалы
  2. componentDidUpdate:

    • Сравнивай prevProps/prevState
    • Избегай бесконечных циклов
    • Обновляй DOM на основе пропсов
  3. componentWillUnmount:

    • Очищай все ресурсы
    • Отписывайся от событий
    • Отменяй таймеры
  4. shouldComponentUpdate:

    • Оптимизируй производительность
    • Используй React.memo вместо этого

Вывод

Жизненный цикл классовых компонентов состоит из трёх стадий:

  • Монтирование — создание и добавление в DOM
  • Обновление — изменение пропсов/состояния
  • Размонтирование — удаление из DOM

В современном React рекомендуется использовать функциональные компоненты с хуками вместо классовых компонентов с их жизненным циклом.