The current popular framework of front-end is to describe the interface with state (state => view). It can be said that front-end development is actually maintaining various states, which has become the consensus of front-end development at present.

View = ViewModel(Model);
Copy the code

Ideally, viewModels are pure functions that, given the same Model, produce the same View.

State => View is easy to understand, but how to properly modify state in view is also a problem.

Why do YOU need state management

For example

The management of the library was originally open, and everyone could come in and out of the library to borrow and return books at will. If the number of people is small, this way can reduce the process and increase efficiency. Once the number of people increases, it is bound to cause chaos.

Flux is like adding an administrator to the library. All borrowing and returning behaviors need to be entrusted to the administrator. The administrator will standardize the operation behavior of the library and record everyone’s operation to reduce the confusion.

A metaphor

The process by which we send something

When there is no delivery:

  • Pack up and get ready to go
  • Just go to your friend’s house and give it to your friend
  • It’s very direct, very convenient, very time-consuming

With express companies:

  • Pack up and get ready to go
  • Go to the express company, fill in the item, the recipient and other basic information
  • The Courier service will deliver your goods to your friend’s house. Our work is done

More express company, let express company send express to us.

When we only send stuff to one friend, it’s less frequent and less stuff, and we just go to the friend’s house. But when we have to send a lot of things to a lot of friends, things get complicated.

The essence of software engineering is managing complexity. Using a state management-type framework has some learning costs and often makes simple things complicated, but if we want to do something a little more complicated (sending a lot of items to multiple addresses at the same time), for us, shipping makes complex things simple.

This also explains whether we need to add a state management framework, depending on our business realities and the preferences of our technical team. In some cases, creating a global object solves a lot of problems.

core idea

The core idea of Flux: one-way flow of data.

  • The states of different components are stored in an external, public Store.
  • Components subscribe to different parts of the Store.
  • The component sends a dispatch action that causes an update to the Store.

The core concept of Redux

  • All states are stored in Store. Each time a component is re-rendered, it must be caused by a state change.
  • The user issues an action on the UI.
  • The Reducer function receives the action and calculates the new state based on the current state.

The Redux Store is a single data source. Redux does not have the concept of dispatcher and uses pure functions instead.

Redux stores are Immutable.

MobX

  • Observable: Its state is Observable, and both basic and reference data types can be converted to Observable value using MobX’s (@) Observable.
  • Reactions: It is a different concept. Computed values, or sending network requests and updating views based on observed data, are all part of response, and Reactive Programming is an application of JavaScript.
  • Actions: This is the source of all responses, such as user Actions on a view or changes to observed data as a result of a response to a network request.

Unlike Redux’s strict specification of one-way data flow, Mobx focuses only on the process from Store to View. In Redux, data changes need to be listened for, whereas Mobx’s data dependency is runtime based, which is closer to Vuex’s.

Vuex status management mode

  • State, the data source that drives the application;
  • View, to declaratively map state to the view;
  • Actions, in response to changes in state caused by user input on the view.

Flux

Facebook came up with the Flux architecture idea, which regulates how data flows through applications. Its basic architecture is shown below. Its core concept is one-way data flow, which improves React’s application state management.

The image above shows how the page gets up and running:

1. Distribute actions through dispatcher and update status and view with action processing logic in store

2. The View can also trigger a new action to proceed to step 1

The action is a simple object describing the action, usually generated by the user’s operation on the view, including the action type and the required parameters carried by the action, such as the action describing the deletion of list items:

{
    type: types.DELETE_ITEM,
    id: id
};
Copy the code

The dispatcher is used to distribute actions to the event handlers registered in the store:

dispatcher.register(function(action) {
  switch (action.type) {
    case "DELETE_ITEM":
      sotre.deleteItem(action.id); // Update the status
      store.emitItemDeleted(); // Notify the view of updates
      break;
    default:
    // no op}});Copy the code

Store contains all the states and logic of an application. It is a bit like the Model layer in the traditional MVC model, but it is obviously different from it. Store contains all the states and logic of an application-specific function, which represents the entire logic layer of an application. Instead of a Model containing records in a database and the logic that goes with them.

Reference: Flux

Redux

The simplest use case for the native Redux API

function counter(state, action) {
  if (typeof state === "undefined") {
    return 0;
  }

  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      returnstate; }}var store = Redux.createStore(counter); //
var valueEl = document.getElementById("value");

function render() {
  valueEl.innerHTML = store.getState().toString();
}

render();
store.subscribe(render);

document.getElementById("increment").addEventListener("click".function() {
  store.dispatch({ type: "INCREMENT" });
});

document.getElementById("decrement").addEventListener("click".function() {
  store.dispatch({ type: "DECREMENT" });
});

document.getElementById("incrementIfOdd").addEventListener("click".function() {
  if (store.getState() % 2! = =0) {
    store.dispatch({ type: "INCREMENT"}); }});document.getElementById("incrementAsync").addEventListener("click".function() {
  setTimeout(function() {
    store.dispatch({ type: "INCREMENT" });
  }, 1000);
});
Copy the code

All states in an application are stored in a single store as a tree of objects. The only way to change state is to trigger an action, an object that describes what happens. To describe how an action changes the state tree, you need to write reducers.

Redux’s Three principles

  • Single data source

    The state of the entire application is stored in an object tree that exists in only one store.

  • State is read-only

    The only way to change state is to trigger an action, which is a generic object that describes events that have occurred.

  • Use pure functions to perform modifications

    To describe how an action changes the State Tree, you need to write reducers. The only way to change state is the Dispatch action. You can subscribe to listen for state changes and then update the UI.

Strict one-way data flow is at the heart of the Design of the Redux architecture.

Redux API

Redux has very few apis.

Redux defines a set of contracts for you to implement (such as reducers) and provides a few helper functions to pull these conventions together.

Redux only cares about managing state. In a real project, you would also need to use a UI binding library such as React-Redux.

  • createStore(reducer, [preloadedState], [enhancer])
  • combineReducers(reducers)
  • bindActionCreators(actionCreators, dispatch)
  • applyMiddleware(… middlewares)
  • compose(… functions)

immutable

When writing redux actions, you always need to use extension statements or object.assign () to get a new state, which is a shallow copy of the Object for JavaScript. The memory overhead is definitely much greater than the direct manipulation of object properties in mobX.

Redux-immutable Seamless – IMmutable ResELECT Why is managing state predictable using REdux

redux-saga

Redux is the state control flow framework in the React stack, which uses standard functional ideas and expects (enforces) all state management to be pure functions. This also means that the states are independent of each other. However, there is a class of state that Redux directly dumped on the third party module, the side effect module Redux-Saga, which has become a typical example of hard work. Side effects are named for their uncertainty and variability, and the states they give interact with each other. How to decouple the original complex nonlinearity into linear logic is exactly where finite state machines come in.

DvaJS

Dva is a data flow solution based on Redux and Redux-Saga. In order to simplify the development experience, DVA also has additional built-in React-Router and FETCH, so it can also be understood as a lightweight application framework.

Within the Redux ecosystem, there are several options for each link. For example, Data can be immutable or plain object. After selecting immutable, use immutable. And whether to use redux-immutable to assist data modification.

Immer DVajs React + Redux best practices

MobX

MobX is a state management library that is easy to use and elegant, yet extensible.

A simple example

import { observable, autorun } from "mobx";

const appState = observable({
  counter: 0,
  add(value) {
    this.counter += value; }}); autorun((a)= > console.log(appState.counter));

setInterval((a)= > appState.add(1), 1000);
Copy the code

In Mobx we can change the state directly

import { observable } from "mobx";

const appState = observable({ counter: 0 });

appState.counter += 1;
Copy the code

This bad practice can be avoided by introducing Strict mode:

import { useStrict } from "mobx";

useStrict(true);
Copy the code

MobX grew out of Reactive Programming, The core idea is that Anything that can be derived from the application state, should be derived. Automatically, you can avoid any repeated state.

The core concept of MobX is Observable, which must be very familiar to those who have been exposed to responsive programming. From RxJava, the typical representative of the back end, to various responsive frameworks in Android/iOS development, they all lead the way.

Similarities and differences with Redux state management

Redux/MobX are both client-side open source state management libraries that use state to describe UI interfaces. They don’t have a strong binding to React, so you can use them with other frameworks. React is a framework for optimizing UI rendering through the Virtual DOM mechanism. Redux/MobX provides a mechanism for synchronizing states to React.

Redux differs from MobX in the following areas:

  • Redux is a single data source, whereas MobX tends to be multiple stores. MobX can organize the Store based on your app’s UI, data, or business logic, and you need to make your own trade-offs.
  • The Redux Store uses the normal JavaScript object structure, while MobX wraps the normal JavaScript object to give an Observable the ability to automatically track observable changes through implicit subscriptions. MobX observes references, and in tracking functions (for example, computed Value, Reactions, and so on), any referenced Observable properties are recorded and MobX reacts when the reference changes. Note that properties that are not in the trace function will not be traced, nor will properties accessed in asynchrony.
  • Redux’s state is read-only and can only be generated by combining the previous state with the triggered action, thus being pure. MobX’s state is readable and writable, and action is optional and can be assigned directly, so it is Impure.
  • Redux requires you to normalize your state, Immutable data so that Reducer needs to copy and update the ancestor data of the state tree when it is updated. The new object will cause all UI components connected to it to be rendered repeatedly. Therefore, Redux state is not recommended for deep nesting, or for use in componentsshouldComponentUpdateOptimization. MobX only updates automatically what you care about and you don’t have to worry about rerendering with nesting.
  • In Redux, smart components are distinguished from dumb components. Dumb is responsible for presentation, while SMART is responsible for status updates and data acquisition. In MobX, however, there is no need to distinguish between them. They are all smart. When the observable that the component depends on changes, it responds.

How Mobx ideas are implemented

The most critical function of Mobx is autoRun. The professional term of autoRun is dependency collection, which means to collect dependencies through natural use. When variables change, the collected dependencies can be used to determine whether updates are needed. Mobx uses Object.defineProperty to intercept getters and setters, just like Vue.

Reference: Mobx Mobx Chinese documentation

Vuex

Vuex is a state management library designed specifically for vue.js. The shared state of components is extracted and managed in a global singleton pattern. It uses centralized storage to manage the state of all components of an application and rules to ensure that the state changes in a predictable way.

The core concept

  • State
  • Getter
  • Mutation
  • Action
  • Module

API

The use of Vuex is simple: commit mutation, dispatch action

Reference link: official Vuex documentation

Finite State machine (FSM)

Finite-state machine (FINite-state machine), also known as finite-state automata, or state machine for short, is a mathematical model that expresses finite states and behaviors such as transfer and action between these states. It is very useful and can simulate most things in the world.

A finite state machine is not a complex concept. In short, it has three characteristics:

  • The total number of states is finite.
  • In one state at any one time.
  • Under certain conditions, they transition from one state to another.

conclusion

States are used to affect views, and actions are responsible for making changes between states. The core of how code is built is to use the most reasonable states to manage the interface and the most reasonable actions to implement changes between states.

State management is actually using finite state machines to manage front-end state.

What finite state machines mean for JavaScript is that many objects can be written as finite state machines.

Before writing code, think about:

  • A page has several states (initialization state? Success status? Failed state? Error state?) .
  • Describe what parameters are required for these states.
  • When to change the state and what to change.

Then follow along and complete the data and UI section.

Javascript -state-machine Xstate Md -state-in-javascript-with-state-machines- Stent