Skip to content

Latest commit

 

History

History
102 lines (72 loc) · 5.11 KB

01-Intro_and_3_Principles_of_Redux.md

File metadata and controls

102 lines (72 loc) · 5.11 KB

01. The Single Immutable State Tree

Video Link

The first principle of Redux:

The entire state of the application will be represented by one JavaScript object.

This holds true regardless of the app's complexity.

All mutations and changes to the state in Redux are explicit.

Everything that changes in the application, including the data and the UI state, is contained in a single object called the state or state tree.

Since the entire state is represented in a single object, we are able to keep track of changes over time.

State in Todo App

"current_state:"
[object Object] {
  todos: [[object Object] {
    completed: true,
    id: 0,
    text: "hey",
  }, [object Object] {
    completed: false,
    id: 1,
    text: "ho",
  }],
  visibilityFilter: "SHOW_ACTIVE"
}

02. Describing State Changes with Actions

Video Link

The second principle of Redux is that the state tree is read only.

You cannot modify or write to it.

Any time you want to change the state, you have to dispatch an action. An action is a plain JS object describing the change. Just like the state is the minimal representation of your app's data, the action is the minimal representation of the change to that data.

There's no set structure for the action object. There's only one requirement: it needs a type property (conventionally a String, since they can be serialized).

For example, a counter app can contain INCREMENT and DECREMENT actions that adjust its count. In the case of a ToDo app, the display components don't know how an item was added to the list — all they know is that an ADD_TODO action was dispatched, with text content "hey" and a sequential id.

This approach scales well to medium and complex apps.

The overall principle here is that the state is read only, and can only be modified by dispatching actions.

03. Pure and Impure Functions

Video Link

Before learning more about Redux, it's important to know the difference between "Pure" and "Impure" functions.

Pure:

function square(x) {
  return x * x;
}
function squareAll(items) {
  return items.map(square);
}

Pure functions are those whose return values depend only upon the values of their arguments. Pure functions don't have side effects (like network or database calls). They also do not override any existing values. Pure functions are predictable: given the same argument(s) , they will always produce the same return value. In the example above, the function returns a new array, instead of modifying the items that was passed in.

Impure:

function square(x) {
  updateXInDatabase(x);
  return x * x;
}
function squareAll(items) {
  for (let i = 0; i < items.length; i++) {
    items[i] = square(items[i]);
  }
}

Contrast this with "impure" functions. Unlike pure functions, impure functions may have side effects, may operate on the DOM, and may override the values you pass to them. In the example above, the function calls a database and overwrites the values that have been passed in.

The distinction between pure and impure functions is important to understand, since Redux will sometimes require you to write pure functions.

04. The Reducer Function

Video Link

React pioneered the idea that the UI layer is most predictable when it is described as a pure function of the application's state.

Redux complements this approach with another idea: that state mutations in your app must be described by a pure function that takes the previous state and the action being dispatched, and returns the next state of your application.

Inside any Redux application, there is one particular function that takes the previous state and the action being dispatched, and returns the next state of the whole application. This function must be pure (i.e. it cannot modify the state given to it) because it has to return a new object representing the application's new state.

Even in large applications, there is still just a single function that calculates the new state of the application. It does so based on the previous state of the whole application and the action being dispatched.

However, this function isn't necessarily slow. If certain parts of the state haven't changed, their references can stay as is. This is what makes Redux fast.

In the ToDo app example, when changing the visibility between "All/Completed/Active" the actual items themselves haven't changed, so the reference to the previous version of the todos array is left intact.

This is the 3rd and final principle of Redux: to describe state mutations, you must write a function that takes the previous state of the app and the action being dispatched, then returns the next state of the app. This function is called the Reducer.

Next ->