We create a calculator-converter based on React. Part 6: Add a converter


We continue the development cycle of the calculator-converter. We have already added most of the necessary options to the calculator, it’s time to understand how the converter could work. Let’s start with the simplest distance conversion and gradually add other types of metrics and formulas.

Previous material: Converter calculator based on React. Part 5: Add a history of results

Create a menu to select the type of interface

We can’t just embed the converter in an existing calculator interface. We need to make a separate interface and a special menu so that we can go to the converter and back. Therefore, we will start with the implementation of such a menu and the decomposition of the App component into new components.

First, load the Chakra-style icon collection to add a Burger icon to the menu as a button to switch to other modes. To do this, open the terminal in the root directory of the project (if you work in VS Code, just press the key Ctrl + `). At the command prompt, enter a command to install Chakra icons.

npm install @chakra-ui/icons

We can now export icons to React components.

Import HambuergIcon icons from ChakraUi

  • In the App.jsx file, create an import of the “Burger” icon.

    import { HamburgerIcon } from '@chakra-ui/icons'

  • Then insert this icon into the App function so that it is displayed in the application interface (you can not apply the style, I increased the size of the icon because it is too small).

    <HamburgerIcon />

The icon is there, and now we need a menu to switch between the converter and the calculator. To do this, create a Menu function in the file App.jsx, and inside put a primitive block Box, which will house the menu interface.

Menu component

The menu for selecting the operating mode of the program can be a simple list of switches. To work with it, we import two more types of elements from Chakra:

import { ListItem, UnorderedList } from '@chakra-ui/react'

Import items to create lists from Chakra

From the added components we will collect the disordered list from three menu items: Calculator,, Converter,, Settings.

The first one is ready, the second one will be made in the near future, and we will deal with the third one at the end. The following template will appear:


List layout

The next step is to add an animation of the menu appearance. By default, it is displayed on a permanent basis, but we need to hide additional options until the user needs them. The SlideFade and useDisclosure components from the Chakra library will help us with this. We import them into our application:

import { SlideFade, useDisclosure } from '@chakra-ui/react'

Import SlideFade component from ChakraUI

You then need to wrap the entire menu interface in the SlideFade component. That is, everything that is part of the Box in the Menu component.

Menu layout with SlideFade component

Next you need to create a special state (unique to the Chakra interface) using Disclosure in the Menu component to control the appearance and disappearance of the menu locked in SlideFade. It contains a variable and a method.

const {isOpen, onToggle} = useDisclosure()

Status of using Disclosure in the Menu component

Now you need to bind the isOpen element as an attribute for the SlideFade component. It is necessary that the menu is displayed in the interface only if the variable changes.

<SlideFade in={isOpen}> </SlideFade>

And the onToggle method binds to the burger menu icon.

<HamburgerIcon onClick={onToggle} />

Menu component code

We will also add an attribute unmountOnExit SlideFade unit so that it is removed from the tree of HTML elements and is not available in the “invisible” state. Otherwise, the user may accidentally click on one of the settings, although the screen does not have this block at all.

UnmountOnExit attribute

The menu itself must be built into the App component and placed above the calculator.

The Menu component in the App component

I recommend adding a position attribute with an absolute value to the Box block in the menu, so that the list of SlideFade items appears on the screen and does not move other parts of the interface in parallel.

The absolute property of the Box element

Also, it may be better to use something like unstyled list, that is, instead of UnorderedList to import into a List file and turn the menu to it. Then unnecessary points will disappear from the interface and the list items will stop moving sideways.

The interface of the Menu component is added

Now we have all the necessary components and you can proceed to the implementation of the logic of switching modes of operation of the program.

The community is now in the Telegram

Subscribe and stay up to date with the latest IT news

Sign up

We make the switch of operating modes of the program

The logic for our menu may be similar to the one we used to switch between InputCalc and ClickCalc. And let’s do it – we will change the state of the App component and on its basis choose which of the interfaces to draw on the screen.

To do this, create a mode state inside the App function.

const [mode, setMode] = useState('Calculator')

Here we declare the application variable to store the component that is displayed now.

Mode status in the App component

Then you can simply copy your own code from other parts of the program. We already have one switch, you can repeat it in the App file. We make function chageAppType.

function changeAppType () { mode == 'Calculator' ? setMode('Converter') : setMode('Calculator') }

As you can see, the logic is repeated – check the active type of component at the moment and replace it if it does not meet user requirements.

Program type change function

We add a switch design. More precisely, copy it from Calculator.jsx, replacing only the variables used. For example, application instead of calculator and Converter instead of ClickCalc.

Switch design for program switching

Replace the component to the {application} variable. And here at a component

you will need to wake up the props with the changeAppType function.

<Menu onClick={changeAppType} />

Application variable in the App component

By this logic, there is a small problem. No matter which list item we click on, it will still switch to the opposite component. That is, there is no fixed and predictable behavior. Therefore, we will still have to make some changes. We will abandon the changeAppType function and delete it.

Fixed Switch design

We will leave the switch design the same. As props in the Menu component we will transfer function setMode. That is, from the menu, we will directly affect the state of the App component, and not check what the current state.

Replace the list items with the Button buttons and attach the function change function of the App component to each button.

  • The first will set the value to Calculator.

    <Button onClick={() => {props.onClick('Calculator')}}> Calculator </Button>

  • And the second will change the state to Converter.

    <Button onClick={() => {props.onClick('Converter')}}> Converter </Button>

Mode switches

Done. Now the menu is more logical and clear where each of the items leads.

We implement the functionality of the converter

Let’s start with a primitive version of the converter, which is able to convert values ​​from one metric unit to another. Let’s take the simplest example – meters and centimeters. Let’s start the implementation of the interface with them, so as not to spend a lot of time, because the basic logic is enough for you to be able to work out the logic for any other options for units other than dynamic. We will analyze them separately in one of these materials.

To begin, create a basic element Select, in which you can select one of the types of metric units. But before that, you need to import the appropriate type of blocks from the Chakra UI library. import { Select } from '@chakra-ui/react'

Import components into the converter

You can now “fold” the basic version of the Select element. It is a list with two values: Centimeters and Meters. Both need to be signed, and the following code will come out:

Select with different types of metrics

  • For centimeters:

    <option value="Centimeters">Centimeters</option>

  • For meters:

    <option value="Meters">Meters</option>

This code must be duplicated, because we will choose the units of measurement in two parts of the interface. We will choose what to convert and in what. To do this, create a function-component Converter and from there return the Flex-block with two Select.

Layout of the block with the converter

We will add Input to the Select blocks to the company. In it we will enter a value that will be converted in the opposite direction. Give it a numeric value so that you can’t enter letters.

<Input type="number">

Input in the Converter component

Below we add a button that starts the conversion process. It will activate a special function that is responsible for both the conversion and the display of the result in the interface. In our case, a fairly simple button labeled Convert.

<Button onClick={() => {convert()}}>Convert</Button>

Select-block with references

Now a few preparatory steps before implementing the conversion logic directly. Let’s create two states: one will be responsible for the value of the Input field, and the other will store the result of the conversion.

I will become a Converter component

const [input, setInput] = useState(0)

const [result, setResult] = useState(0)

We also need to create two referents to directly access the Select elements in the converter interface.

References in the Converter component

For now, let’s just call them first and second:

const first = useRef()

const second = useRed()

useRed is a hook function that allows you to interact with HTML elements within a single React component. You do not need to search for it manually using the queryselector method. You have something like a specific name for the HTML element.

Next we need to create a function to change the value of input, or rather to bind the change in the state of input when entering characters in the line Input. To do this, add the appropriate attribute to the corresponding HTML element.

<Input onChange={(e) => {setInput(e.target.value)}} />

The setInput function in the Converter block

Here we attach the first reference. To do this, find the block with the necessary data and specify as the attribute ref the name of the reference created inside the component. For example, in the case of one Select will receive a reference first.

<Select ref={first}

This allows us to obtain information about the selected unit of measure by specifying the variable first or second in the body of the methods used in the Converter function.

We create a convert method. This method first checks which unit is set in the first Select. If it is meters, then the method goes to the formulas developed for this unit. In our case, the switch construct is used, which selects the formula according to which unit of measurement is specified in the second reference. Here is the whole code item by item.

Convert function

  • Declaring the convert function:

    function convert() { }

  • We check the first reference for compliance with the value of Meters. To do this, turn to the current element and its value.

    if (first.current.value == 'Meters') { }

  • In the body of the test when it is successfully executed, the switch structure enters the course, it takes as a basis the value of the second reference.

    switch(second.current.value) { }

  • Inside the switch construct, all possible values ​​and formulas for them are searched. So far we have only two cases: Centimeters and Meters. For centimeters, the formula for multiplying the value of meters by 100 is indicated.

    case 'Centimeters': setResult(input * 100); break

  • And in the case of meters, you do not need to change anything.

    case 'Meters': setResult(input * 100); break

Formulas for calculating distances

We will repeat this code for centimeters. That is, we create a check for compliance with the first reference value of Centimeters, then again include the construction switch, but with formulas for centimeters. For example, to convert centimeters to meters, you need to make a case that divides the input by a hundred.

case 'Meters': setResult(input / 100); break

Instead of imprisonment

The basic converter is ready. Now all you have to do is add new formulas and add new values ​​to the interface elements. I recommend making formulas to other functions or components to store them in a separate file. Here they can take up too much space, interfering with the perception of the code.

If you have questions, leave comments. Next, create a more advanced converter that retrieves data from the network.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2022 ZoNa365.ru - Theme by WPEnjoy · Powered by WordPress