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

Приведи пример использования componentDidMount в React

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

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

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

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

Использование componentDidMount в React

componentDidMount — это жизненный метод класса React-компонента, который вызывается сразу после монтирования компонента в DOM. Это ключевое место для выполнения side effects, таких как загрузка данных из API, подписка на события, инициализация сторонних библиотек или работа с DOM.

Основные сценарии применения

1. Загрузка данных из API

Наиболее распространённый случай — выполнение AJAX-запросов для получения начальных данных компонента.

import React from 'react';

class UserProfile extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      user: null,
      loading: true,
      error: null
    };
  }

  componentDidMount() {
    // Идеальное место для загрузки данных
    fetch(`https://api.example.com/users/${this.props.userId}`)
      .then(response => {
        if (!response.ok) throw new Error('Network response was not ok');
        return response.json();
      })
      .then(data => {
        this.setState({ user: data, loading: false });
      })
      .catch(error => {
        this.setState({ error: error.message, loading: false });
      });
  }

  render() {
    const { loading, error, user } = this.state;
    
    if (loading) return <div>Загрузка профиля...</div>;
    if (error) return <div>Ошибка: {error}</div>;
    
    return (
      <div>
        <h1>{user.name}</h1>
        <p>Email: {user.email}</p>
      </div>
    );
  }
}

2. Инициализация сторонних библиотек

Многие библиотеки (например, карты, графики) требуют DOM-элемента для работы, который доступен только после монтирования.

import React from 'react';
import Chart from 'chart.js';

class AnalyticsChart extends React.Component {
  chartRef = React.createRef();
  chartInstance = null;

  componentDidMount() {
    const ctx = this.chartRef.current.getContext('2d');
    
    // Инициализируем график только после монтирования
    this.chartInstance = new Chart(ctx, {
      type: 'line',
      data: this.props.chartData,
      options: { responsive: true }
    });
  }

  componentWillUnmount() {
    // Очистка при размонтировании
    if (this.chartInstance) {
      this.chartInstance.destroy();
    }
  }

  render() {
    return <canvas ref={this.chartRef} width="400" height="200"></canvas>;
  }
}

3. Подписка на события и внешние изменения

class WindowResizeTracker extends React.Component {
  state = { windowWidth: window.innerWidth };

  componentDidMount() {
    // Подписываемся на событие resize только после монтирования
    window.addEventListener('resize', this.handleResize);
  }

  componentWillUnmount() {
    // Обязательно отписываемся при размонтировании
    window.removeEventListener('resize', this.handleResize);
  }

  handleResize = () => {
    this.setState({ windowWidth: window.innerWidth });
  };

  render() {
    return (
      <div>
        Ширина окна: {this.state.windowWidth}px
      </div>
    );
  }
}

Ключевые особенности componentDidMount

  • Вызывается один раз — после первоначального рендеринга компонента
  • DOM доступен — к этому моменту компонент уже добавлен в DOM
  • Идеально для side effects — безопасное место для операций вне React
  • Не блокирует рендеринг — выполняется после отрисовки компонента

Современные альтернативы

С появлением React Hooks, аналогичную функциональность можно реализовать с помощью useEffect:

import React, { useState, useEffect } from 'react';

function UserProfileFunctional({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    // useEffect с пустым массивом зависимостей работает аналогично componentDidMount
    fetch(`https://api.example.com/users/${userId}`)
      .then(response => response.json())
      .then(data => {
        setUser(data);
        setLoading(false);
      })
      .catch(err => {
        setError(err.message);
        setLoading(false);
      });
  }, []); // Пустой массив зависимостей = выполняется только при монтировании

  if (loading) return <div>Загрузка...</div>;
  if (error) return <div>Ошибка: {error}</div>;
  
  return (
    <div>
      <h1>{user.name}</h1>
    </div>
  );
}

Важные предостережения

  • Избегайте вызовов setState синхронно после componentDidMount — это может вызвать лишний ререндер
  • Всегда очищайте side effects в componentWillUnmount, если создавали их в componentDidMount
  • Не используйте для инициализации состояния, которое зависит от пропсов — для этого лучше подходит constructor или getDerivedStateFromProps

componentDidMount остаётся важной частью React для классовых компонентов, предоставляя надёжную точку для инициализации, которая требует наличия DOM и гарантирует однократное выполнение.

Приведи пример использования componentDidMount в React | PrepBro