We are creating a converter calculator based on React. Part 9: Connecting Redux and Router

Let’s talk about important and popular third-party libraries for React: Redux and Router. Why are they needed and how can these libraries be applied in practice. I will use the example of the calculator that we created in the previous parts of the cycle.

Previous part: Calculator converter based on React. Part 8: Currency Converter and Custom Data Parser

What is Redux?

Redux is a third-party library for managing the state of JavaScript applications. You already know how component states work in React. So Redux allows you to transfer these states from a bunch of different elements to a single control system that is separate from other project files, but always within reach. That is, the state of multiple components can be stored in a single repository. It can be updated from any React component and displayed in any React component.

Redux allows you to simplify the complex structures of passing data from parent components to descendants and from descendants back to parents.

It’s hard to say how appropriate it is to use Redux in our application. A lot of copies have already been hacked on this topic, and I will not repeat articles on the topic of how important it is to use certain technologies only in those situations when they are really needed. I’ll just show a basic example of how Redux works, and you can decide for yourself if you need it here. Or you can simply learn how to work with Redux and be able to use it in other applications.

We install Redux

First, you need to download the utility itself as an npm package and pull all dependent packages along with it to fully configure the basic version of the state store.

  • Open a terminal in the directory with our project.

  • Enter the command npm install react-redux

  • Then enter npm install @reduxjs/toolkit

After both commands work, you can proceed to the settings directly in the program.

Basic Redux setup

To begin with, we need to decide how Redux will be used in general and what we need it for. Since the number of Redux application scenarios is limited only by the imagination of programmers, no one can name the specific reasons for using Redux.

In our case, Redux will store the history of any calculations. Whether calculations in the calculator or some operations performed by the converter. That is, our History field will turn into a public space into which you can transfer information from any mode of operation of the program to save the received values.

With this information in mind, let’s move on to creating our first Redux repository.

First, we create the store.js file and save it in our project. This will be a JavaScript document containing the state of the components.

File manager in VS Code

As the content of the store.js file, you need to specify the basic Redux configuration with references to related components and an object that stores the state of the components.

Configuration of the store.js file

  • Import the configureStore configuration file.


    
    import { configureStore } from '@reduxjs/toolkit'

  • Then import the state change function using Redux (we’ll create it later).


    
    import historyReducer from './historySlice'

  • After that, we export the already changed configureStore object to external spaces (so that it can be accessed from third-party program components). Inside it, we specify the reducer function responsible for changing the Redux state.


    
    export default configureStore({ reducer: { history: historyReducer, }, })

Having finished with the repository, we move on to creating a state change method. It will be in the historySlice.js file that we will create in the root of the project.

And here is its content:

The contents of the historySlice file

  • Import the createSlice function from @reduxjs/toolkit:


    
    import { createSlice } from '@reduxjs/toolkit'

  • Creating a variable containing a call to the createSlice function with the necessary data:


    
    export const historySlice = createSlice( )

  • As an argument for createSlice, an object with all the necessary information and methods for state management will appear:


    • Name name: history

    • Standard state – initialState: { value: []}

    • State management methods (reducer function). In our case, this is the updateHistory function, which accepts arguments from third-party components when called and processes them inside Redux.


updateHistory: (state, action) => 
  state.value.push(action.payload)
}

After declaring each element and describing the state management method, it remains to export it to the external environment to then import it into the application.

  • We export the method.


    
    export const { historyUpdate } = historySlice.actions

  • We export the state.


    
    export const historyState = state = state.history.value

  • We export the reducer method completely.


    
    export default historySlice.reducer

done You can go to the second part.

We connect Redux to our program

We have an external state, but it is currently not being used in any way in our application. We will change it from two components of our program, and it will be displayed in the general part of the interface, visible when using both the calculator and the converter.

To work with Redux states in a React application, you need to import the store and the Provider component into the root file of the application (in our case, it is index.js).

It will be:


import store from './components/store'

import { Provider } from 'react-redux'

Import Redux components

Provider is a parent component-wrapper, in which you need to put all the code of the application in its entirety. We used to build ChakraProvider. Therefore, it should also be placed inside the Provider from Redux. It is also important not to forget to pass store as an argument to Provider.


<Provider store={store}> </Provider>

Connecting the Redux provider to the React application

First, let’s add our external state to the Converter component to fully test it and see if it works at all.

We import the entire list of elements we need.

  • Hooks from the Redux library:


    
    import { useSelector, useDispatch } from 'react-redux'

  • Methods and state from our historySlice file:


    
    import { updateHistory, historyState } from '../historySlice

Import hooks from Redux

Next, we create variables for them inside the Converter component. The history variable should use the useSelector hook on the history state to store it in the component, and the dispatch variable allows you to quickly call the useDispatch() hook.

State management variables in Redux

Next is the matter of technology. To display the history state in the interface, we simply write the corresponding variable in the return method of the Converter component. And to change it, let’s create a separate key that activates the dispatch method.

In our case, we need to pass a request to Redux to run the updateHistory method with the result argument (since we plan to pass the calculation value in the converter).


<Button onClick={() => dispatch(updateHistory(result))}

History variable with Redux

A similar interface will appear. It shows the result of converting one measurement unit to another and a button to send this value to the history state.

Converter interface

When you click on this button, the conversion result will go into the Redux history state and will be displayed above.

Add to history button to change Redux state

The problem is that we don’t get the benefits of Redux because the history is not visible in other elements. We need to show the state in the interface at a higher level so that we can always see it, not only when working with the converter. After all, according to the original plan, the function of changing the state should work from several different components.

Therefore, we import the same data from Redux and historySlice, but already into the App component. There, we will create a variable history that addresses the hook using the Selector, and return it to the turn.

Redux state in the interface of the App component

Now you can add the Add to history button to any program component, including the calculator. It will work in the same way as any other similar buttons in the application.

Add to history button in the calculator interface

You can slightly modify the contents of the history variable in the App component so that the state items are displayed in individual buttons.

Changed the rendering code of the operation history

The following interface will appear.

History state in Redux

Also, in our application, Redux can simplify the process of implementing Drag&Drop.

The community is now in Telegram

Subscribe and stay up to date with the latest IT news

Sign up

What is a Router

Router is a popular tool for React programs and one of the most important components of any web application, which allows you to associate individual components of your project with specific addresses in the browser.

Each component for the browser looks exactly like a separate page, which allows you to leave links to individual components of the program. For example, in our case, you can create a link immediately to the calculator, and not to the converter (or vice versa). It will also help save the state of the program when it is restarted. Now when pressing F5, we automatically switch to the calculator.

We install the Router

We will use React-Router. There are other routing options, but I found this one to be the easiest. It is the easiest to understand, and the installation process is included in one command.

After the command is finished, we proceed to the routing settings in the application.

Connect the Router to our program

The router is connected quite easily, as well as other third-party libraries. You just need to wrap the application in the component that comes with React Router.

Import the required component into index.js.


import { BrowserRouter } from 'react-router-dom'

Now we turn our program into a router. You need to “put” everything below the ChakraProvider in the BrowserRouter, as shown in the screenshot.

Router wrapper

After that, we go to the routing settings in the App.js component. Since this is practically the root of our program, from here we will move to different parts of the tool we have created.

We import here three components that are responsible for the basic functionality of the router. This is the Routes block, which will hold all the paths (links to individual components of the program), the Route block, which stores a separate component for rendering, and the Link element, which allows you to switch between different elements of the page.


import { Routes, Route, Link } from 'react-router-dom'

Now the paths need to be placed in the interface. You can safely write them in the return method of the component that is the root of your application. All of them will not be displayed at once, because routing works as conditional rendering, that is, the content displayed on the page will depend on the currently selected path.

Routing settings

  • Instead of the application variable used earlier, we create a Router block.


    
    <Routes> </Routes>

  • Inside the block, we specify all the necessary ones on the path, prescribing for them a link and a component that must be displayed:


    • The path to the base component (that is, what will be displayed in the application interface by default). Since we do not have a main screen or its analogue in the program, we will issue a calculator in the basic way:


      
      <Route path="/" element={<Calculator />} />

    • Path to the converter:


      
      <Route path="converter" element={<Converter />} />

    • Path to the calculator:


      
      <Route path="calculator" element={<Calculator />} />

It remains to make an interface for switching between paths. We already have a menu that is responsible for conditional rendering (that is, the one that allows you to select the value of the application variable inside the App component). Here we modify it, replacing the buttons that change the value of the application variable with Link elements, as well as the URL address in the address bar of the browser.

List of links to routes in the menu

  • For a calculator, this element will look like this:


    
    <Link to="/calculator">Calculator</Link>

  • For the converter – like this:


    
    <Link to="/converter">Converter</Link

Here’s what the app will look like when you launch it (note the address bar).

Base link

And this is what will happen if you go to the converter in the menu.

Route to the React converter

Now when entering the address manually /converter you’ll get to the right part of the app, and that app state won’t be reset on page reloads.

Instead of imprisonment

We explored two important elements of React applications that are often used in projects of various scales. Even if they are not needed in such a small application as a calculator, they will be needed in other web services.

Related Posts

Leave a Reply

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

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