React to the state

React Redux

I’ve been working with web development with React Redux for some time now and I would like to share some key points to why I recommend you to try it out.

React has been around for 4 years now and it is maintained by Facebook. It’s an open source library for rendering web pages in JavaScript. Since it’s written in JavaScript, React can be used to render html either in the browser or on the server side or a combination of both. Rendering is simply a function that transforms properties into html. React uses virtual DOM to make updates fast and does a good job at optimizing which parts of the DOM that needs to be changed.

Redux, as described by their web page, is a predictable state container for JavaScript apps. The idea of Redux is to store the whole state in an object tree in a single place and the only way to change the state is to emit actions. Actions are used by reducers to produce the next state.

Before we go any deeper in to what that means, let’s quickly go through two important concepts, immutability and pure functions.

Immutability

An immutable object cannot be changed. That´s it.

This has some effects that need to be considered. For one, to update an attribute on that object, a copy must be made with the updated value included. As a result, a lot of objects may need to be created in the process of making many updates. Just think of a loop adding an element to an empty list. For 10 elements, 10 different lists will be created. This may sound bad, but if the data structures are implemented in a good way, the cost may not be that big. There are libraries out there to help working with immutability.

A big benefit of immutable objects is the fact that they are thread safe. You don´t need to worry about different parts of the program working at the same time with your objects.

This is usually not a problem when the application is small enough for a single developer to know every detail of. But in a larger architecture and with different developers maintaining separate parts, immutability works like an insurance that the data is kept intact.

In a situation with high performance demands, mutable object may be preferred to make special optimization either for speed or memory gain. Though in my experience, these cases are rare.

Pure functions

A pure function in programming is a function that always gives the same result for the given arguments. The function must not modify the input in any way or change any state. It cannot depend on any state in- or outside of the function that may change during execution. It may only depend on the input or constants to produce a result.

To illustrate this let´s look at some simple examples. First a pure function:

function f1(x) {
return x + 1;
}

The function will always return the same result for a given x. The following function is not pure since it modifies the input argument.

function f2(array, value) {
array.push(value);
return array;
}

If the function f2 is called twice with the same arguments it will yield two different results since it modifies the array.

What are the benefits of using pure functions then? Why bother to create a new array when we easily can add an element to the end? Pure functions give predictability and can help avoid complex test scenarios needed to cover all situations when state is changing. The result of a pure function is cacheable, if it always returns the same result for a given argument, then it doesn’t matter how that result is produced.

Redux

Let’s get back to Redux. The state in redux is a single tree structure contained in a store. It should be treated as immutable even though the actual objects, as any object in JavaScript, are mutable. As mentioned earlier, the way to update the state in Redux is to dispatch an action. An action, doesn’t do anything by itself, it’s merely a description of what the user intended to happen. The update, or the creation of the next state of the application, is the job for reducers.

A reducer is pure function that takes the current state and an action as arguments and returns the next state. It is very important here that the function is pure and never modifies the current state, never performs any I/O or depends on any external values. This in turn makes the state predictable. If we know a state and what actions came later, we can always calculate the new state with the same result at any time.

Redux reducers operate on different parts of the state and are combined into a single reducer responsible for the whole state. The state and reducers are therefore modular and different aspects of an application can be implemented and tested separately.

UI as a function of state

Creating a visual component in React is simple. You basically write a function that transforms properties to html. The function should be a pure function and by using JSX, you can mix html tags with your other React component as tags. This makes it easy to read and understand, but it’s still a function like any other.

React Redux lets you connect the properties of the React component to any part of the state. If your state is updated by an action, the UI is re-rendered automatically to reflect these changes.

If you express the UI as a function of state and the next state a function of state and action:

UI = f(state)
nextState = reducer(state, action)

Then the next UI can be expressed as:

UI2 = f(nextState) = f(reducer(state, action))

Knowing the current state and action, you always know what your UI will be. However, keep in mind that this only holds true if you stick to pure function and keeping the state immutable. React will re-render the whole UI in the virtual DOM but only update the browser’s DOM where needed.