Создание React‑компонента часов с автоподновлением

Сохраните идентификатор интервала, очищайте его при размонтировании и обновляйте дату через setState. Прямое присваивание this.state.date не запускает корректное обновление React.

Короткий ответ

Что ответить на собеседовании

Сохраните идентификатор интервала, очищайте его при размонтировании и обновляйте дату через setState. Прямое присваивание this.state.date не запускает корректное обновление React.

Подробный разбор

Ответ с пояснениями

Условие

Требуется адаптировать приведённый ниже код так, чтобы отображаемое время обновлялось каждую секунду.

import React from 'react'

class Clock extends React.Component<any, any> {
  constructor(props) {
    super(props)
    this.state = { date: new Date() }
  }

  componentDidMount() {
    setInterval(
      () => this.tick(),
      1000
    )
  }

  componentWillUnmount() {
    clearInterval()
  }

  tick() {
    // @ts-ignore
    this.state.date = new Date()
  }

  render() {
    return (
      <div>
        <h1>Привет, мир!</h1>
        <h2>Сейчас {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    )
  }
}

Ответ

Сохраните идентификатор интервала, очищайте его при размонтировании и обновляйте дату через setState. Прямое присваивание this.state.date не запускает корректное обновление React.

В существующем классе замените соответствующие методы:

private timer?: ReturnType<typeof setInterval>;

componentDidMount() {
  this.timer = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
  if (this.timer !== undefined) clearInterval(this.timer);
}
tick() {
  this.setState({ date: new Date() });
}

Конструктор и render можно сохранить. Новую дату берём с часов при каждом tick, не прибавляем условную секунду: фоновые вкладки и занятый event loop задерживают таймеры.

Источник: react.dev.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее