Using Redux in React

Dec 4, 2018 · 4 min read · 696 Words · -Views -Comments

Recently I worked on Project A with a React + Redux stack. My React foundation was weak and Redux was new, so I ran into many issues. After reading docs and practice, I now have a basic understanding and record it here.

For Redux, those who know it say it’s simple, those who don’t say it’s hard. Is it really hard? Not really. Let me explain.

Before talking about Redux in React, let’s address a few questions. Understanding them helps a lot.

Why do SPAs exist?

Redux was created to solve state management in SPAs, so we should understand why SPAs exist. When we used jQuery, we didn’t need Redux. We should not use Redux or React just because others do. If it’s unnecessary, why add complexity?

Recommended reading: The Fundamental Reason Why Modern JS Frameworks Exist.

Modern frontend frameworks mainly solve UI and state synchronization.

  • Modern JS frameworks mainly solve the problem of UI and state synchronization.
  • Using only native JS makes it difficult to write complex, efficient, and maintainable UI code.
  • Web components don’t solve this main problem.
  • Although it’s easy to create a framework that solves this problem using virtual DOM libraries, it’s not recommended that you actually do this.

What problems does Redux solve for SPAs?

SPAs make frontend development more systematic but bring state management problems. Redux emerged to address this. The Redux official site explains it well:

As the requirements for JavaScript single-page applications have become increasingly complicated, our code must manage more state than ever before. This state can include server responses and cached data, as well as locally created data that has not yet been persisted to the server. UI state is also increasing in complexity, as we need to manage active routes, selected tabs, spinners, pagination controls, and so on.

Managing this ever-changing state is hard. If a model can update another model, then a view can update a model, which updates another model, and this, in turn, might cause another view to update. At some point, you no longer understand what happens in your app as you have lost control over the when, why, and how of its state. When a system is opaque and non-deterministic, it’s hard to reproduce bugs or add new features.

React vs Redux

Concepts (from official docs):

React

A JavaScript library for building user interfaces

Redux

Redux is a predictable state container for JavaScript apps

react-redux

From the above, they are unrelated libraries solving different layers. In development we often face both problems, so React projects use Redux for complex state management. The glue is react-redux, which you can think of as the React version of Redux.

Using Redux in React

Now that we understand the big picture, let’s learn the basics.

For basic Redux learning, I recommend the official site and revisiting it often.

Install Redux

npm i redux --save-dev
npm i react-redux --save-dev

Create Action, Reducer, Store

Action

Reducer

Store

dispatch

See code here

Relationship between the three

If you don’t understand the three pillars, see the diagram below:

Let’s break it down:

  • Components trigger actions via store.dispatch()
  • Actions kick off operations, reducers compute the new state
  • Store belongs to Redux. In React, a component has state and props. Redux store is reflected into component props for consumption. The connect function connects the store to the component.

Using helper functions

In addition to redux itself, it’s recommended to use helper libraries to standardize and improve the experience.

redux-actions-helper

I used this in my project to help with actions.

export const initSettingAction = createAction(
  SettingActionTypes.UPDATE_SETTING,
  (inherit: ISetting, base: ISetting) => ({
    inherit,
    base
  })
);

const updateSettingReducer = (state: ISettingState, action: IAction<{ inherit: ISetting; base: ISetting }>) => ({
  ...state,
  ...action.payload
});

Benefits:

  1. It enforces that action parameters are separated from type, matching Flux: payload and type are siblings, all params live under payload.
  2. IAction type definition enforces type safety for actions.

Redux Toolkit

The official team released a toolkit; new projects can consider it.

Click here

Final Thoughts

You should now have a basic understanding. This post is mostly fundamentals. Internal skills matter most. Once you know the why, the rest is practice.

References

Authors
Developer, digital product enthusiast, tinkerer, sharer, open source lover