architect-handbook

Software Architect Handbook

View on GitHub

Redux Introduction

What is Redux/

Redux is a pattern and library for managing and updating application state, using events called “actions”. It serves as a centralized store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion.

Why should I use Redux?

Redux helps you manage “global” state (state that is needed across many parts of your application).

The patterns and tools provided by Redux make it easier to understand when, where, why, and how the state in your application is being updated, and how your application logic will behave when those changes occur.

Redux guides you towards writing code that is predictable and testable.

When should I use Redux?

There are more concepts to learn, and more code to write. It also adds some indirection to your code, and asks you to follow certain restrictions. It’s a trade off between short term and long term productivity:

Core Terminology

Take a look at Redux Documentation.

State Management

In a self-contained app with the following parts:

Traditional way

We can observe a “one-way data flow”:

one-way data flow

However, the simplicity can break down when we have multiple components that need to share and use the same state, especially if those components are located in different parts of the application. Somethimes this can be solved by “lifting state up” to parent components, but that doesn’t always help.

One way to solve this is to extract the shared state from the components, and put it into a centralized location outside the component tree. With this, our component tree becomes a big “view” and any component can access the state or trigger actions, no matter where they are in the tree.

By defining and separating the concepts involved in state management and enforcing rules that maintain independence between views and states, we give our code more structure and maintainability.

This is the basic idea behind Redux: a single centralized place to contain the global state in your application, and specific patterns to follow when updating the state to make the code predictable.

Redux way

redux flow

Immutability

In order to update values immutably, your code must make copies of existing objects/arrays, and then modify the copies. Redux expects that all state updates are done immutably.

Actions

An action is a plain JavaScript object that has a type field. You can think of an action as an event that describes something that happened in the application.

The type field should be a string that gives this action a descriptive name. We usually write that type string like "domain/eventName".

An action object can have other fields with additional information about what happened. By convention, we put that information in a field called payload.

const addTodoAction = {
  type: 'todos/todoAdded',
  payload: 'Buy milk'
}

Action Creators

An action creator is a function that creates and returns an action object. We typically use these so we don’t have to write the action object by hand every time.

const addTodo = text => {
  return {
    type: 'todos/todoAdded',
    payload: text
  }
}

Reducers

A reducer is a function that receives the current state and an action object, decides how to update the state if necessary, and returns the new state: (state, action) => newState. You can think of a reducer as an event listener which handles events based on the received action (event) type.

Reducers must always follow some specific rules:

The name “reducer” comes from Array.reduce(). We can say that Redux reduce a set of actions (over time) into a single state. The difference is that with Array.reduce() it happens all at once, and with Redux, it happens over the lifetime of your running app.

Store

The current Redux application state lives in an object called the store.

The store is created by passing in a reducer, and has a method called getState that returns the current state value.

Dispatch

The Redux store has a method called dispatch. The only way to update the state is to call store.dispatch() and pass in an action object. The store will run its reducer function and save the new state value inside.

You can think of dispatching actions as “triggering an event” in the application.

Selectors

_Selectors are functions that know how to extract specific pieces of information from a store state value. This can help avoid repeating logic as different parts of the app need to read the same data.