Building a Calculator App with Redux and Onsen UI

There are many frameworks and concepts around in the JavaScript world. In today’s blog post we are going to write a pure mobile JavaScript application with Onsen UI and Redux, which is a very small but powerful library that enables to write JavaScript applications in a conceptually different way.

Redux is inspired by Flux, which was developed by Facebook. Unlike Flux, Redux is quite flexible and does not require any specific infrastructure like GraphQL. We will use Redux in combination with Onsen UI to build a simple Calculator mobile app. One of the nicest things about this app is that it will look native, both on Android and iOS, due to Onsen’s autostyle feature.

All the source code is freely available at https://github.com/philolo1/OnsenUI-redux-calculator/.

Understanding Redux

Let’s first see what Redux is and how it works. Redux consists of three main components:

  • Store: This structure stores the complete state of our application. Given only the content of the store, the application should be able to save and recover the current state of the application.
  • Actions: Actions are how the application interacts with the store. The application sends an action with some attached data. These actions are than handles by a so called reducer.
  • Reducer: The Reducer is a function that takes the current state and an action and transforms it to a new state.

In addition to these three components, there are three principles of how a redux application should be written.

  1. Single Source of Truth: As mentioned previously the store is the only place where data is stored. This enables the application to do nice things like undoing an action and also helps to more easily debug.
  2. The state is read-only: The state of the application can only be changed via actions. This is very useful for debugging, since the changing state flow is much more clear.
  3. The reducer consists only of pure functions: Pure functions are functions that do not change the parameter object they are given.

The first two points should be very clear. For the second one lets have a look at what a pure function is. Let’s say we want to create a function handleLoaded, that should add the property isLoaded: true to the state:

As you can see, we need to be careful to write pure functions and don’t manipulate the parameters. If the function wasn’t pure, it would be hard to recover the previous state and would make debugging much harder because of side effects.

Calculator: HTML + CSS

Now that we have understood the basics, let’s create our Calculator app. The calculator consists of 6 rows: The first one will be a simple div that contains the display, the remaining rows will consist of buttons of the calculator. For simplicity, we will only support integer manipulation. Combined with the power of ons-button and ons-page we get:

There is now real magic going on here. Every row is split equally across the screen and every column has equal height using flexbox and percentages. The colors of the buttons are done by different opacity. CSS contains only a few lines of code:

Calculator: JavaScript Code

To write the JavaScript code we need to first think about the state and actions of our application. For the actions we use:

  • TYPE : This action indicated that a number is typed on the calculator.
  • CHANGE_SIGN : This action indicates a change of the sign (‘+’/‘-‘) of the display.
  • CLEAN : This action will reset the calculator.
  • EQUAL : This action will be triggered when the = is pressed.
  • OPERATION : This action will be called whenever we press an action button that will do a mathematic operation with two operands.

We can now already write some part of our JavaScript code:

The Redux Framework manages the store. We will need to give it our reducer with Redux.createStore(ourReducer), which we will define later. Since we want to rerender every time the state changes, we need to listen to the store. Fortunately, Redux provides us with a function store.subscribe to which we pass our render function.

The complicated part is writing the reducer. Our reducer will have four states:

  • number: This represents the number that will be displayed on the screen.
  • operation: This will store the last operation function, that has been calculated like plus, minus etc.
  • storedFunc: This function will be used to store results and operations that are not directly displayed. For example, if we type 1 +, the value of the storedFunc will be (x) => 1 + x. This makes evaluation quite easy since we have to only call storedFunc(num).
  • originalFunc: This function is necessary to support repeating the last operation for the ‘=’ sign.
  • lastAction: This piece of data should contain the last action that has been done.

Now that we have the state and actions, we only need to write the reducer. We will split our reducer into two, one for adding the lastAction and the other one doing the main state transformation.

Next, we will write our general reducer that handles all the actions. We will split the reducer up into multiple functions:

It should be noted here that at the beginning of our application, the state will be undefined, that is why we need to define our initial state with number: 0 to display 0 at the beginning. Now we need to define the handleEqual and handleOperation function. As stated previously we take advantage of our storedFunc and operation states.

And now we are done and have our app perfectly working! It might take a while to get used to this code thinking, but we could give you a small glance at the word of redux and functional programming.

Resources

The source code is available here. We only covered a small app that shows how to develop in Redux. There are tons of resources on the internet. I truly can recommend the video tutorial: https://egghead.io/lessons/javascript-redux-the-single-immutable-state-tree and having a look at https://github.com/reactjs/redux. If any questions arise, feel free to ask it on our Community Forum.

Like what you read? Give Onsen UI & Monaca Team a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.