How to Overcome Redux Neverending Code With 2 Simple Libraries

Front-end development made a giant leap from static web pages to interactive single-page applications. The complexity of business logic has grown exponentially and state management became one of the top objectives to solve. A sloppy architecture can slow down the whole development process and ineffective state management can cost you a substantial amount of resources. Or even make your app unusable. Luckily, there are two libraries that significantly improve the developers’ work as well as the overall app performance – Immer and Redux-Persist.

Immer to save your day… from tedious coding

Do you remember the first time you had to write a reducer? First, declare a state in a reducer file. Then, list the action type constants in a separate file, and last – write actions and action creators. And on top of that, TypeScript adds an extra layer of complexity. Whenever you needed to add something new to your reducer, you had to make changes in at least three files. This amount of boilerplate code slows down the development process, reduces the team’s productivity, and it is prone to errors.

Since Redux is just a library and not a framework, there are an infinite number of ways to structure the project. The more separate files you have, the more variations are possible. Choosing project architecture becomes like constructing a house of cards. The more pieces you have, the higher is the possibility that one misplaced card could collapse the whole assembly.

The creators of the award-winning library Immer (“Breakthrough of the year”; “Most impactful contribution”) have addressed the problem with the boilerplate coding. Their solution will change your whole attitude about Redux.

How does it work?

“Using Immer is like having a personal assistant. The assistant takes a letter (the current state) and gives you a copy (draft) to jot changes onto. Once you are done, the assistant will take your draft and produce the real immutable, final letter for you (the next state).”

I will show you a sample react native app to compare the amount of code you have to write, with and without the library. We will use the most common action with states – set, update, and clear a state, also add, update, and remove an item from a collection. For the setup, we will apply TypeScript to see that the IntelliSense works well with this library.

I will skip the initial setup phase. If you need it, take a look at the official documentation. 

The versions with and without Immer will be saved in three separate branches and you will be easily able to compare the different outcomes. The app will fetch the top 100 Hacker news and list them on the initial screen. From that list the user will be able to preview articles or save them in Favorites. On the Favorites screen the user can see, preview, or remove saved articles. On the History screen the user can scroll through the already previewed stories.

Those three screens will manipulate arrays of data. Finally, on the Settings screen, there will be settings for background color and font size. You will see how Immer reduces the clutter when manipulating nested states.

 

Setup Steps

  1. Install the library

npm install immer-reducer

 

  1. In your reducer file add the following line:

import {ImmerReducer, createReducerFunction, createActionCreators} from ‘immer-reducer’;

 

  1. Declare a state interface if you are using TypeScript.

 

Now instead of using the regular reducer declaration, declare a reducer class that extends the generic ImmerReducer and then pass the interface to the same class. 

In this same class, set the actions and the state updates. You can notice that we are not using the spread operator anymore and to omit the spread operator is especially helpful for nested states.  Check the update of the Settings state if you want to see an example.

createActionCreators generates all actions from the declared reducer. That means NO MORE boilerplate code for action types, actions, and action creators in different files. Now everything is in one place. Also, you don’t have to declare action interfaces as createActionCreators generates typed functions.

You don’t have to use type and action files from the boilerplate. What is left is the reducer and the saga files. The action creators are typed.

At the end of the reducer file, export the actions and the reducer.

redux

Let’s use the generated action creators. First, call it in the saga file. There we still need action types. The good news is they are also generated by Immer.  Just import the actions, select the required one and get the type by calling the property type. To dispatch/put an action, import the action creator and select from there the action.

action creator redux

And this is how you access the state and dispatch the actions in your view.

dispach

Redux-Persist = never losing your memory

One of the biggest optimizations for every app is memoization. Redundant loading of data can make your app insanely slow. The first and straightforward solution could be storing the state in a local store as a stringified json and loading it every time the app starts. 

Redux-Persist is one of the most elegant solutions. It is a set-and-forget kind of deal. You only have to decide which states you want to persist. All the rest of the work will be handled by the library.

Setup steps

  1. Install the library

npm install redux-persist

 

  1. Add the following lines in your redux store configuration:

import { Persistor, persistReducer, persistStore } from ‘redux-persist’;

import storage from ‘redux-persist/lib/storage’;

 

  1. Add a configuration

 

  1. Provide storage in the configuration. We will use AsyncStorage but you could also use encrypted storage. To install it just type npm install @react-native-async-storage/async-storage.

 

  1. Whitelist the reducers you want to persist. For this project, it is relevant to persist Favorites, History, and Settings.

 

  1. Create a persisted reducer by passing the configuration and the root reducer to the persistReducer function. Next, apply the persisted reducer when creating a store.

 

  1. Finally, create and export a persistor, which will be provided in the root of the app.

 

This is how your store file should look.

 

persistreducer

The final step is to provide the persistor to the app. Now you can preview a couple of articles, save some favorites and set a background color. After restarting the app, the persisted state will be loaded and ready to use.

app

The Outcome

Immer and Redux-Persist are two lightweight libraries that can significantly reduce the boilerplate code you need to write and optimize the work of your whole team. There is no steep learning curve and newly joined developers can effortlessly get the hang of the project’s state management. The persisted state makes your app work blazing fast and vastly improves the user experience. Immer and Redux-Persist are undoubtedly two of the major improvements in state management.

Repo: https://github.com/GeorgiSpasov/immer-redux-persist

Georgi is a mobile and web developer with experience in building telemedicine solutions. He is passionate about solving logic puzzles and is also an Arduino/IOT enthusiast.

x

Motion Software starts operating under the name of its parent company Exadel, taking effect on July 15th.

More Info

Motion Software uses cookies to improve site functionality, provide you with a better browsing experience, and to enable our partners to advertise to you. Detailed information on the use of cookies on this Site, and how you can decline them, is provided in our Cookie Policy Learn more about cookies, Opens in new tab. By using this Site or clicking on OK, you consent to the use of cookies.

OK