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

Какие методы жизненного цикла можно реализовать в классовом компоненте?

1.3 Junior🔥 111 комментариев
#Фреймворки и библиотеки

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

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

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

Методы жизненного цикла в классовых React компонентах

Классовые компоненты в React имеют набор методов жизненного цикла (lifecycle methods), которые позволяют выполнять код на различных этапах существования компонента. Хотя в современном React предпочитают функциональные компоненты с хуками, понимание lifecycle методов остаётся важным для работы с legacy кодом и интервью.

Три основные фазы жизненного цикла

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

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

constructor(props)

constructor(props) {
  super(props);
  this.state = { count: 0 };
  // Инициализация, привязка методов
  this.handleClick = this.handleClick.bind(this);
}
  • Выполняется первым
  • Инициализация state и привязка методов
  • Единственное место, где можно присвоить this.state напрямую
  • Не должен содержать side effects

static getDerivedStateFromProps(props, state)

static getDerivedStateFromProps(nextProps, prevState) {
  if (nextProps.id !== prevState.id) {
    return { id: nextProps.id };
  }
  return null;
}
  • Редкий метод, вызывается перед render
  • Используется когда state зависит от props
  • Возвращает новый state или null
  • Без доступа к this

render()

render() {
  return <div>{this.state.count}</div>;
}
  • Обязательный метод
  • Возвращает React элемент
  • Должен быть чистой функцией без side effects
  • Может вызваться несколько раз

componentDidMount()

componentDidMount() {
  fetch('/api/data')
    .then(res => res.json())
    .then(data => this.setState({ data }));
  // Подписка на события
  window.addEventListener('resize', this.handleResize);
}
  • Вызывается после render и добавления в DOM
  • Идеальное место для AJAX запросов
  • Установка таймеров, подписок
  • Единственное место где это безопасно делать

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

Этап изменения props или state:

static getDerivedStateFromProps(props, state)

  • Тот же метод, что в mounting, но может вызваться несколько раз

shouldComponentUpdate(nextProps, nextState)

shouldComponentUpdate(nextProps, nextState) {
  if (nextProps.id === this.props.id && 
      nextState.count === this.state.count) {
    return false; // Пропустить перерендер
  }
  return true;
}
  • Оптимизация производительности
  • Возвращает true (перерендер) или false (пропустить)
  • По умолчанию возвращает true
  • Обычно заменяется React.memo для функциональных компонентов

render()

  • Вызывается снова при обновлении

getSnapshotBeforeUpdate(prevProps, prevState)

getSnapshotBeforeUpdate(prevProps, prevState) {
  // Сохранить позицию скролла перед обновлением
  return { scrollY: window.scrollY };
}
  • Редкий метод, вызывается перед обновлением DOM
  • Результат передаётся в componentDidUpdate
  • Используется для сохранения информации о DOM

componentDidUpdate(prevProps, prevState, snapshot)

componentDidUpdate(prevProps, prevState, snapshot) {
  if (prevProps.id !== this.props.id) {
    // Выполнить действие при изменении props
    this.fetchData();
  }
  // snapshot содержит результат getSnapshotBeforeUpdate
  if (snapshot) {
    window.scrollTo(0, snapshot.scrollY);
  }
}
  • Вызывается после обновления DOM
  • Идеальное место для сравнения с предыдущим состоянием
  • Безопасно вызывать setState, но нужна условная логика чтобы избежать infinite loop
  • Не вызывается при первом монтировании

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

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

componentWillUnmount()

componentWillUnmount() {
  // Очистка подписок
  window.removeEventListener('resize', this.handleResize);
  // Отмена таймеров
  clearTimeout(this.timerId);
  clearInterval(this.intervalId);
  // Отмена AJAX запросов
  this.abortController?.abort();
}
  • Вызывается перед удалением из DOM
  • Последний шанс очистить ресурсы
  • Отмена подписок, таймеров, запросов
  • Очень важен для предотвращения утечек памяти

Deprecated методы (НЕ использовать)

Старые методы, которые удалены в React 18+:

  • componentWillMount → заменить на constructor или componentDidMount
  • componentWillReceiveProps → заменить на getDerivedStateFromProps
  • componentWillUpdate → заменить на getSnapshotBeforeUpdate

Практический пример: загрузка данных

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

  componentDidMount() {
    this.fetchUser();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.userId !== this.props.userId) {
      this.fetchUser();
    }
  }

  fetchUser = () => {
    this.setState({ loading: true });
    fetch(`/api/users/${this.props.userId}`)
      .then(res => res.json())
      .then(user => this.setState({ user, loading: false }))
      .catch(error => this.setState({ error, loading: false }));
  }

  componentWillUnmount() {
    // Отмена запросов если необходимо
  }

  render() {
    const { user, loading, error } = this.state;
    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;
    return <div>{user.name}</div>;
  }
}

Современный подход: Hooks

В функциональных компонентах используются хуки вместо lifecycle методов:

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

  useEffect(() => {
    setLoading(true);
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(setUser)
      .finally(() => setLoading(false));
  }, [userId]); // componentDidMount + componentDidUpdate

  useEffect(() => {
    // componentWillUnmount
    return () => {
      // Очистка
    };
  }, []);

  if (loading) return <div>Loading...</div>;
  return <div>{user?.name}</div>;
}

Лучше использовать функциональные компоненты с хуками в новом коде, но понимание классовых компонентов остаётся важным для работы с legacy приложениями и интервью.