Как я сделал погодное приложение в стиле Terraria на React: история любви, пикселей и TypeScript

Демонстрация работы

Идея, которая пришла из любви

Всё началось с обычного вечера. Мы с моей девушкой, для которой Terraria является одной из самых любимых игр, решили перепройти её вместе. Погружаясь в этот блочный пиксельный мир, я смотрел на дожди, песчаные бури и метели и думал: "А ведь было бы круто, если бы обычная погода за окном выглядела так же атмосферно".

Идея засела в голове. Так родился мой первый масштабный проект. Это не просто ещё одно погодное приложение. Это моя попытка соединить ностальгию по пиксельной эстетике, мощь современных веб-технологий и личную историю.

Что получилось в итоге

Я создал полноценное SPA-приложение со следующим функционалом:

  • Поиск города: Получение актуальной погоды для любого населённого пункта.
  • Детализация погоды: Отображение текущей температуры, ощущаемой температуры, скорости ветра, влажности и описания.
  • 5-дневный прогноз: Прогноз на ближайшие 5 дней.
  • Избранное: Возможность сохранять любимые локации, чтобы быстро проверять погоду в них. Данные хранятся в localStorage.
  • Конвертер температур: Переключение между градусами Цельсия и Фаренгейта.
  • Адаптивный пиксель-арт интерфейс: Уникальный дизайн, вдохновлённый Terraria, который корректно отображается как на десктопе, так и на мобильных устройствах.

Технологический стек

Выбор технологий был продиктован желанием изучить и применить на практике самые востребованные инструменты фронтенда:

  • React: Выбор в пользу функциональных компонентов и хуков.
  • TypeScript: Для типизации и предотвращения ошибок на этапе разработки.
  • Open-Meteo API: Бесплатный, простой и мощный API погоды с подробной документацией.
  • Tailwind CSS: Для быстрой и гибкой стилизации с утилитарным подходом.
  • date-fns: Для удобного форматирования и работы с датами.
  • Vite: В качестве инструмента для сборки проекта – быстрый и современный.

С какими вызовами столкнулся и как их решал

Путь от идеи до работающего приложения не был усыпан розами. Вот два самых интересных вызова:

1. Типизация данных от внешнего API

Проблема: Ответ от Open-Meteo – это большой сложноструктурированный JSON-объект. Без чёткой типизации легко ошибиться в пути к нужному свойству (weather.temperature? weather.current.temperature?).

Решение: Я не стал полагаться на any и тщательно описал все интерфейсы TypeScript на основе документации API. Это не только свело количество runtime-ошибок к нулю, но и стало отличной документацией внутри кода.

2. Работа с состоянием и localStorage

Проблема: Нужно было организовать хранение избранных городов и предпочтений по температуре так, чтобы состояние в React и данные в localStorage всегда были синхронны. Наивный подход вроде "записывать в localStorage при каждом изменении" вёл к потенциальным багам.

Решение: Я инкапсулировал эту логику в кастомные хуки. Эти хуки при инициализации читают данные из localStorage, а при любом изменении состояния автоматически обновляют его. Это чистое и переиспользуемое решение.

Чему я научился

Этот проект стал для меня не просто строчкой в портфолио, а настоящим учебным полигоном:

  • Глубже понял TypeScript: Осознал мощь типизации для работы с внешними API и сложными структурами данных.
  • Укрепил знания по управлению состоянием: На практике применил концепцию кастомных хуков для side effects.
  • Поработал с асинхронностью: Организация загрузки данных, обработки состояний загрузки и ошибок.
  • Прокачал навыки работы с Tailwind CSS: Научился быстро создавать адаптивные и визуально приятные интерфейсы.

Заключение

Создание этой работы показало мне, что лучшие проекты рождаются на стыке страсти к технологиям и личных увлечений. Это был бесценный опыт, который стартовал с простой идеи, предложенной любимым человеком.

Ссылки по теме:

Исходный код можете посмотреть на гитхабе https://github.com/tugbaev04/terraria-weather

А вам приходили необычные идеи для проектов из повседневной жизни? Делитесь в комментариях!


И также подписывайтесь на мой телеграм, там будут выходить новости о будущих проектах

1
2 комментария