К списку заданий

ДЗ к уроку №3

Дедлайн 11.11.2025 в 20:59

Задание: Реализация счетчика с Context API и кастомным хуком

Ссылочки

  • Репозиторий с которого нужно начать разработку

  • В файле Task.md , найдете тз

  • Сдача дз проводится с помощью github forks / pull requests (см. доп урок в курсе по фронтенду, либо в дз №1 по курсу реакта)

  • В качестве сданной домашки принимаются ссылки на pull request

Цель задания

Изучить и применить на практике:

  • Работу с Context API для глобального состояния

  • Создание и использование кастомных хуков

  • Public API для модулей

  • CSS модули для стилизации

Задача

Реализовать модуль счетчика counter) по аналогии с модулем темы theme), который уже реализован в проекте.

Требования

1. Структура модуля

Создайте модуль counter в папке src/modules/counter/ со следующей структурой:

modules/counter/

├── contexts/

│ ├── counter-context.tsx # Типы и создание контекста

│ └── counter-provider.tsx # Провайдер с логикой счетчика

├── hooks/

│ # Кастомный хук для счетчика

├── ui/

│ # Ваши компоненты с css модулями

└── index.ts # Public API модуля

2. Context API

Создайте контекст счетчика:

- counter-context.tsx: Определите типы и создайте контекст

- Тип: CounterContextType с полями: count: number, increment: () => void, decrement: () => void, reset: () => void

- Создайте CounterContext с помощью createContext

- counter-provider.tsx: Реализуйте провайдер

- Используйте useState для хранения состояния счетчика

- Начальное значение: 0

- Реализуйте функции: increment, decrement, reset

- use-counter-context.ts: Создайте хук для использования контекста

- Используйте useContext для получения контекста

- Добавьте проверку на использование вне провайдера с понятным сообщением об ошибке

3. Кастомный хук

Создайте кастомный хук use-counter.ts:

- Хук должен принимать initialValue (по умолчанию 0)

- Возвращать объект с полями: count, increment, decrement, reset

- Использовать useState для хранения состояния

- Функция reset должна возвращать счетчик к initialValue

4. UI компоненты

Создайте два компонента:

counter-with-context.tsx:

  • Использует useCounterContext для получения состояния из контекста

  • Отображает текущее значение счетчика

  • Кнопки: "+1", "-1", "Сброс"

  • Используйте CSS модули для стилизации

counter-with-hook.tsx:

  • Использует кастомный хук useCounter(0)

  • Отображает текущее значение счетчика

  • Кнопки: "+1", "-1", "Сброс"

  • Используйте CSS модули для стилизации

5. CSS модули

Создайте стили для обоих компонентов:

  • Используйте разные цвета границ для визуального различия

  • Стилизуйте кнопки

  • Добавьте hover эффекты

  • Используйте медиа-запросы для поддержки светлой/темной темы

6. Интеграция в App

В src/app/app.tsx:

  • Добавьте CounterProvider (можно вложить в ThemeProvider)

  • Отобразите оба компонента: CounterWithContext и CounterWithHook

  • Добавьте несколько экземпляров каждого компонента, чтобы показать разницу:

  • CounterWithContext - общее состояние для всех экземпляров

  • CounterWithHook - независимое состояние для каждого экземпляра

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

import {

    CounterProvider,

    CounterWithContext,

    CounterWithHook,

} from '../modules/counter'

;<CounterProvider>

    <CounterWithContext />

    <CounterWithContext /> {/* Использует то же состояние */}

    <CounterWithHook /> {/* Свое состояние */}

    <CounterWithHook /> {/* Свое независимое состояние */}

</CounterProvider>

Ожидаемое поведение

1. CounterWithContext: Все экземпляры компонента используют одно и то же состояние (при изменении в одном, меняется во всех)

2. CounterWithHook: Каждый экземпляр компонента имеет свое независимое состояние

Критерии оценки

  • Корректная реализация Context API

  • Рабочий кастомный хук

  • Использование CSS модулей

  • Код следует примерам из модуля theme

  • Нет ошибок TypeScript (проверить можно командой npm run build)

Подсказки

  1. Изучите реализацию модуля theme - он служит примером для реализации

  2. Обратите внимание на использование useLocalStorage в ThemeProvider - это хороший пример кастомного хука

  3. Используйте useContext для получения контекста

  4. Не забудьте обработать случай, когда хук используется вне провайдера

Дополнительные задания (по желанию)

  • Сохранять значение счетчика в localStorage (используя useLocalStorage)

  • Добавить возможность задавать шаг инкремента/декремента

  • Добавить анимации при изменении значения

  • Реализовать историю изменений счетчика

Поступи на курс, чтобы сдавать задания на проверку преподавателям