🟨 React
Средняя
🕐 15 мин

React таймер

Цель: создать таймер на React с использованием хуков, эффектов и интервалов.

💡 Подсказка к решению

Для создания таймера вам понадобится:

  1. Состояние: Используйте хуки useState для хранения времени и useRef для хранения идентификатора интервала.
  2. Эффекты: Используйте хук useEffect для управления побочными эффектами.
  3. Интервалы: Используйте setInterval для обновления времени каждую секунду.
  4. Форматирование: Преобразуйте секунды в формат MM:SS для отображения.
  5. Управление: Реализуйте функции для запуска, остановки и сброса таймера.
// Пример использования useState и useRef
const [seconds, setSeconds] = useState(0);
const intervalRef = useRef(null);
 
// Пример запуска таймера
const startTimer = () => {
  intervalRef.current = setInterval(() => {
    setSeconds(prev => prev + 1);
  }, 1000);
};
👀 Решение
import React, { useState, useRef, useEffect } from 'react';
 
export default function Timer() {
  // Состояние для хранения секунд
  const [seconds, setSeconds] = useState(0);
  // Состояние для отслеживания активности таймера
  const [isActive, setIsActive] = useState(false);
  // Ref для хранения идентификатора интервала
  const intervalRef = useRef(null);
 
  // Эффект для управления интервалом
  useEffect(() => {
    if (isActive) {
      intervalRef.current = setInterval(() => {
        setSeconds(prevSeconds => prevSeconds + 1);
      }, 1000);
    } else if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }
 
    // Очистка интервала при размонтировании компонента
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, [isActive]);
 
  // Функция для запуска таймера
  const startTimer = () => {
    setIsActive(true);
  };
 
  // Функция для остановки таймера
  const stopTimer = () => {
    setIsActive(false);
  };
 
  // Функция для сброса таймера
  const resetTimer = () => {
    setSeconds(0);
    setIsActive(false);
  };
 
  // Функция для форматирования времени в MM:SS
  const formatTime = (secs) => {
    const minutes = Math.floor(secs / 60);
    const seconds = secs % 60;
    return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
  };
 
  return (
    <div style={{ textAlign: 'center', margin: '20px' }}>
      <h2>Таймер</h2>
      <div style={{ fontSize: '32px', margin: '20px 0', fontFamily: 'monospace' }}>
        {formatTime(seconds)}
      </div>
      <div>
        <button 
          onClick={startTimer}
          disabled={isActive}
          style={{
            padding: '8px 16px',
            margin: '0 5px',
            backgroundColor: '#4CAF50',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: isActive ? 'not-allowed' : 'pointer',
            opacity: isActive ? 0.7 : 1
          }}
        >
          Старт
        </button>
        <button 
          onClick={stopTimer}
          disabled={!isActive}
          style={{
            padding: '8px 16px',
            margin: '0 5px',
            backgroundColor: '#f44336',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: !isActive ? 'not-allowed' : 'pointer',
            opacity: !isActive ? 0.7 : 1
          }}
        >
          Стоп
        </button>
        <button 
          onClick={resetTimer}
          style={{
            padding: '8px 16px',
            margin: '0 5px',
            backgroundColor: '#2196F3',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer'
          }}
        >
          Сброс
        </button>
      </div>
    </div>
  );
}

Анализ решения:

  • Состояние: Используем хуки useState для хранения секунд и состояния активности таймера, а также useRef для хранения идентификатора интервала.
  • Эффекты: Хук useEffect управляет запуском и остановкой интервала в зависимости от состояния активности.
  • Интервалы: setInterval обновляет счетчик каждую секунду, когда таймер активен.
  • Форматирование: Функция formatTime преобразует секунды в формат MM:SS для удобного отображения.
  • Управление: Реализованы функции для запуска, остановки и сброса таймера с соответствующими проверками состояния.
  • Стилизация: Добавлены стили для улучшения внешнего вида компонента и индикации состояния кнопок.

Описание задачи

Вам нужно создать компонент таймера на React. Компонент должен отображать время в формате MM:SS и предоставлять кнопки для управления таймером.

Ключевые требования:

  • Начальное значение таймера должно быть 00:00
  • Кнопка “Старт” должна запускать таймер (увеличивать значение каждую секунду)
  • Кнопка “Стоп” должна останавливать таймер
  • Кнопка “Сброс” должна сбрасывать таймер на 00:00
  • Таймер должен корректно управлять интервалами и избегать утечек памяти

Примеры

// Базовый пример компонента таймера
<Timer /> // Отображает 00:00 и кнопки Старт, Стоп, Сброс
 
// После нажатия на кнопку Старт и ожидания 5 секунд
// Отображает 00:05 и кнопки Старт (неактивна), Стоп, Сброс
 
// После нажатия на кнопку Стоп
// Отображает 00:05 и кнопки Старт, Стоп (неактивна), Сброс
 
// После нажатия на кнопку Сброс
// Отображает 00:00 и кнопки Старт, Стоп, Сброс

Требования

  • Компонент должен называться Timer
  • Используйте хуки useState, useEffect и useRef для управления состоянием и эффектами
  • Реализуйте функции для запуска, остановки и сброса таймера
  • Добавьте форматирование времени в формате MM:SS
  • Убедитесь, что таймер корректно очищает интервалы при остановке и размонтировании
  • Стилизация компонента приветствуется, но не обязательна

🧑‍💻 Это не баг! Это фича!

Редактор кода намеренно скрыт на мобильном.

Поверь, так лучше: я оберегаю тебя от искушения писать код в неидеальных условиях. Маленький экран и виртуальная клавиатура — не лучшие помощники для программиста.

📖 Сейчас: Изучи задачу, продумай решение. Действуй как стратег.

💻 Потом: Сядь за компьютер, открой сайт и реализуй все идеи с комфортом. Действуй как код-джедай!