Skip to content

Latest commit

 

History

History

introduction

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Redux Introduction

  • What is Redux?
  • Why should I use Redux?
  • When should I use Redux?
  • Core Terminology
    • State Management
    • Immutability
    • Actions
    • Action Creators
    • Reducers
    • Store
    • Dispatch
    • Selectors

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:

  • You have large amounts of application state that are needed in many places in the app.

  • The app state is updated frequently over time.

  • The logic to update the state may be complex.

  • The app has a medium or large-sized codebase, and might be worked on by many people.

Core Terminology

Take a look at Redux Documentation.

State Management

In a self-contained app with the following parts:

  • State: Source of truth that drives our app.

  • View: Declarative description of the UI based on the current state.

  • Actions: Events that occur based on user input, and trigger updates in the sate.

Traditional way

We can observe a "one-way data flow":

  • State describes condition of the app at a specific point in time.

  • UI is rendered based on that state.

  • When something happens, the state is updated based on what occurred.

  • UI re-renders based on the new state.

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

  • Initial setup

    • Redux store is created using a root reducer function.

    • Store calls the root reducer once, and saves the return value as its initial state.

    • When UI is first rendered, UI components access the current state of the Redux store, and use that data to decide what to render. They also subscribe to any future store updates so they can know if the state has changed.

  • Updates

    • Something happens in the app, such as a user clicking a button.

    • The app code dispatches an action to the Redux store.

    • The store runs the reducer function again the previous state and the current action, and saves the return value as the new state.

    • The store notifies all parts of the UI that are subscribed that the store has been updated.

    • Each UI component that needs data from the store checks to see if the parts of the state they need have changed.

    • Each component that sees its data has changed forces a re-render with the new data, so it can update what's shown on the screen.

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:

  • They should only calculate the new state value based on the state and action arguments.

  • They are not allowed to modify the existing state. Instead, they must make immutable updates, by copying the existing state and making changes to the copied values.

  • They must not do any asynchronous logic, calculate random values, or cause other "side effects".

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.