Реклама ООО Таймвэб
Реклама ООО Таймвэб

Создаем калькулятор-конвертер на базе React. Часть 4: Декомпозиция и мелкие исправления

Обсудить
Создаем калькулятор-конвертер на базе React. Часть 4: Декомпозиция и мелкие исправления

Продолжаем разработку калькулятора-конвертера на базе Реакта с визуальной библиотекой Chakra. В этой статье речь пойдет о декомпозиции, а также устранении мелких недочетов в коде и изменении некоторых аспектов дизайна. Слегка причешем нашу программу, а также подготовим ее для добавления новых функций и внедрения конвертера в грядущих материалах.

Предыдущий материал: Калькулятор-конвертер на базе React. Часть 3: Автоматический подсчет результатов

Зачем нужна декомпозиция?

Разбиение приложения на части мотивировано необходимостью иметь полный контроль над каждым аспектом программы, чтобы можно было легко найти нужный кусок кода и при желании внести в нем изменения. Также деление программы на части позволяет сделать отдельные компоненты интерфейса или логики независимыми друг от друга. Это, в свою очередь, делает итоговый продукт более отказоустойчивым. Даже если одна из частей ПО выйдет из строя, она не затронет другие (при правильной настройке, конечно). 

Мы начнем разбивать единый блок с кодом на отдельные файлы, чтобы проще было добавлять в интерфейс новые составляющие. 

Комьюнити теперь в Телеграм
Подпишитесь и будьте в курсе последних IT-новостей
Подписаться

Разбиваем приложение на части

Взгляните на наш примитивный калькулятор. Он пока способен только на выполнение элементарных расчетов, но уже растянулся на внушительное количество кода. Получается довольно масштабное полотно, за которым тяжело следить. Здесь трудно находить нужные составляющие и редактировать их. Если бы все составляющие калькулятора были размещены в отдельных файлах, то часть проблем, связанных с читабельностью кода, попросту исчезла бы. 

Код калькулятора в одном файле

Начнем с того, что создадим отдельную директорию в папке src, где лежат наши jsx-файлы. Назовем ее components и создадим три отдельных компонента: Calculator, ClickCalc и InputCalc. 

Реакт-компоненты

Что касается последних двух, то их менять почти не придется, а вот первый придется заметно скорректировать, так как это будет совершенно новый элемент. Похожая судьба ждет компонент App.jsx, который практически лишится кода на текущий момент.

Ниже на скриншоте видно, как может выглядеть компонент InputCalc, находясь в отдельном файле. Особых отличий здесь увидеть не получится. Это та же React-функция, с той же логикой и аналогичным интерфейсом, возвращенным из метода return.

Содержимое компонента InputCalc

Из нового тут только экспорт. Чтобы этот компонент был доступен внутри других элементов приложения, нужно его экспортировать:

export default InputCalc

Аналогичную процедуру нужно проделать во всех выделенных в отдельные файлы компонентах, чтобы сразу можно было импортировать их в другие участки калькулятора. Важно отметить, что экспортировать надо только корневой объект, а функции, подключаемые внутри одного файла, экспортировать не нужно. Например, не стоит экспортировать Numbers и CountButton из файла ClickCalc. Функция ClickCalc и так сообщит о существовании этих объектов другим компонентам. 

Экспорт функции в JavaScript

Следующий шаг – создание родительного компонента для выбора режима отображения калькулятора. Напомню, что в прошлой статье мы делали смарт-строку, автоматически считающую значение выражений, вводимых в специальный input-элемент. Но он существует по соседству с обычным калькулятором, что нас не устраивает. По моей задумке, эти режимы должны быть независимыми и находиться в разных участках интерфейса. Также должна быть предусмотрена возможность менять режимы по клику на одну кнопку. Реализацией подобной функциональности мы сейчас и займемся. 

В файле Calculator будет следующий код:

React-компонент Calculator

  • Сначала импортируем все нужные компоненты из библиотеки Чакры. 

    import { Box, Text, Button, Input, Flex } from '@chakra-ui/react'
  • Импортируем функцию useState:

    import { useState } from 'react'
  • Импортируем файл ClickCalc (сразу можно захватить и другой режим):

    import ClickCalc from '.ClickCalc'
  • Создаем функцию Calculator:

    function Calculator () { }
  • В теле функции прописываем ее состояние. В нашем случае – calcType. В нем будет отражаться режим калькулятора, используемый в конкретный момент времени. Значение по умолчанию оставляем ClickCalc, чтобы первое, что видел пользователь при открытии нашего приложения – стандартный калькуляторный интерфейс. 

    const [calcType, setCalcType] = useState('ClickCalc')
  • Также создаем переменную calculator, которая будет хранить в себе компонент с нужным режимом. 

  • Эту же переменную возвращаем из функции Calculator:

    return ( <Box> {calculator} </Box> )

Теперь нужно добавить конструкцию switch, меняющую значение переменной calculator в зависимости от того, какого рода калькулятор мы хотим видеть перед собой. 

Конструкция Switch в компоненте Calculator

  • Прописываем саму конструкцию с нужным значением: 

    switch (calcType) { }
  • В теле switch прописываем два кейса. Первый для ситуации, когда должен работать стандартный калькулятор:

    case 'ClickCalc': calculator = <ClickCalc />; break;
  • А второй для смарт-поля для подсчета с помощью функции eval:

    case 'InputCalc': calculator = <InputCalc />; break;
  • И кейс по умолчанию:

    default: calculator = <ClickCalc />

Теперь нам нужна кнопка, отвечающая за переключение между двумя режимами работы приложения. Добавим Button в интерфейс, обернув переменную calculator и кнопку в единый Box. 

Интерфейс калькулятора, поделенного на компоненты

У кнопки должна быть функция переключения. Она выглядит так: 

onClick={() => { calcType == 'ClickCalc' ? setCalcType('InputCalc') : setCalcType('ClickCalc') }}

Эта функция проверяет значение состояния calcType и меняет его на другое в зависимости от того, что указано в момент клика (используется тернарный оператор ?). 

Функция переключения между калькуляторами

Эту функцию можно перенести в тело компонента, а в интерфейсе оставить только обращение к ней по клику, как указано ниже. 

Верстка калькулятора

Нам осталось только импортировать Calculator в файл App.

Импорт компонента Calculator в корень приложения

Как видите, предварительно мы удалили почти весь код из файла App. Осталось только два импорта и возврат нужного нам компонента. Пока этого достаточно. Наш переключатель и два разных калькулятора готовы.

Корректируем разрешение и положение объектов

Теперь переходим ко всяким мелочам. Например, скорректируем интерфейс. Сейчас он довольно мелкий и вечно сползает, потому что указаны некорректные значения высоты и ширины. 

Рекомендую выставить фиксированное значение ширины 90% у объекта, отрисовывающего текущее значение в строке для подсчетов. Так он перестанет прилипать к стенам. 

Верстка блока ClickCalc

Уберите фиксированное значение высоты у всех элементов (кроме главного, что указан в компоненте App.jsx), чтобы они не влияли на положение программы в интерфейсе. 

Измените размер кнопок, сделайте их больше. Я выбрал ширину и длину в 60 пикселей. 

Кнопки с измененным размером

В таком случае элементы выглядят достаточно крупно на мобильном устройстве. 

Интерфейс калькулятора на мобильном устройстве

Меняем тему оформления

Также мы можем расширить возможности используемой темы. Мне не нравится в коде ПО указывать цвета при помощи hex-значений, поэтому я создал объект theme внутри App и прописал для используемых цветов более понятные названия (вы можете выбрать имена на свой вкус).

Объект с расширенной темой для Chakra UI

  • Импортируем в App.jsx функцию для расширения списка свойств стандартной темы Chakra. 

    import { extendTheme } from '@chakra-ui/react'
  • Создаем переменную с функцией extendTheme и указываем там измененные свойства темы:

    const theme = extendTheme({ colors: { capri: '#00C0F9, tomato: '#FF6347, }, })'
  • Затем добавляем атрибут theme в ChakraProvider:

    <ChakraProvider theme={theme}> </ChakraProvider>

Другие небольшие изменения

Добавим еще несколько мелких изменений, ради которых жалко начинать новый материал. 

Добавим в список возможностей кнопки «Равно» полное обнуление поисковой строки, чтобы не приходилось стирать введенные значения. Кстати, стоит добавить отдельную кнопку на тот случай, если нужно стереть все введенные знаки.

Кнопка уравнивания выражений

Изменим массив с числами. Пропишем все цифры вручную, чтобы соблюсти порядок, который веками используется в калькуляторах и привычен всем, кто с ними соприкасался. К тому же мы сможем добавить в список кнопок еще и запятую. 

const nums = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', ',']... 

Компонент, отвечающий за рендеринг цифр

После этого у нашего калькулятора будет более привычный облик (за исключением немного кривой верстки).

Обновленный интерфейс калькулятора с новым порядком чисел

Работу со смарт-калькулятором можно упростить, если добавить автоматическую фокусировку на поле ввода. Не придется тянуться к нему и кликать мышью. 

Для этого воспользуемся функцией useEffect, которую прежде импортируем в компонент InputCalc:

import { useState, useEffect } from 'react'

Импорт React-хука useEffect

Затем объявим эту функцию внутри InputCalc, а в ее теле пропишем JavaScript-метод для фокусировки на input-элементе. 

useEffect(() => { document.querySelector("input").focus() })

Фокусировка на элементе при помощи useEffect

Вместо заключения

На этом все. Мы разделили приложение на фрагменты и устранили ряд проблем. Теперь снова перейдем к реализации новых функций. Если возникнут какие-то вопросы или советы, то обязательно оставляйте их в комментариях.

Продолжение: Калькулятор-конвертер на базе React. Часть 5: Добавляем историю результатов

Hello World! Гайды и обзоры для девелоперов разных мастей.

Комментарии

С помощью соцсетей
У меня нет аккаунта Зарегистрироваться
С помощью соцсетей
У меня уже есть аккаунт Войти
Инструкции по восстановлению пароля высланы на Ваш адрес электронной почты.
Пожалуйста, укажите email вашего аккаунта
Ваш баланс 10 ТК
1 ТК = 1 ₽
О том, как заработать и потратить Таймкарму, читайте в этой статье
Чтобы потратить Таймкарму, зарегистрируйтесь на нашем сайте