This paper is a summary of Flux, Redux, Vuex and MobX common state management modes, which tends to the conceptual level and does not involve too much code.

State management

What is state management?

State management is to extract the states that need to be shared between components and manage them in a unified manner according to specific conventions so that state changes can be predicted.

Why do YOU need state management?

State sharing

There are usually some shared states between components. In Vue or React, these states are generally promoted to the props of the common parent component. The parent component manages the shared states in a unified manner, and state changes are executed and transmitted downward by the parent component. This leads to two problems:

  • The shared state needs to be promoted to a common parent, and if there is no common parent, you often need to construct it yourself
  • State is passed layer by layer from parent to parent, and if there are too many layers of components, data transfer becomes cumbersome

Change tracking

During application debugging, it may be necessary to trace the state change process, which facilitates the repetition and tracing of certain application scenarios. In this case, the state needs to be managed uniformly, and specific conventions are followed to change the state so that the state changes are predictable.

Store model

The Store mode is a relatively simple state management mode, which generally has the following conventions:

  • State is stored in external variablesstoreIn (can also be a global variable)
  • storeIn thestateUsed to store datastoreExamples of maintenance
  • storeIn theactionsEncapsulate changestateThe logic of the

The flow chart is as follows:

If changes to state are brought to actions, it is easy to record changes, save snapshots, and roll back history, but the Store mode does not enforce this.

Flux

Flux is an architectural idea, similar to MVC, MVVM, etc.

The composition of Flux

Flux divides an application into four parts:

  • View: The View layer
  • Action: actions, i.e., message objects that change data (can be triggered by events, test cases, etc.)
    • Store changes can only be made through Action
    • The processing logic for specific actions is usually stored in the Store
    • The Action object contains the type and payload.
  • -Dispatcher: Take Actions, send them to all stores
  • Store: Data layer, Store application status and update status method, once changes, remind Views to update the page

Notice:

  • An Action is essentially a purely declarative data structure that provides only a description of the event, not the specific logic of the event. It’s usually given to the ActiontypeProperty assigns an uppercase string to indicate a constant to enhance maintainability, for example:
{
  type: 'ADD_USER'.payload: {
    name: 'user_name'}}Copy the code

The characteristics of the Flux

  • One-way data flow. The view event or external test case issues an Action via the Dispatcher to the Store, which triggers methods to update the data and update the view
  • There can be multiple stores
  • A Store not only stores data, but also encapsulates methods for processing it

Redux

The composition of the story

  • Store: Storage application status —stateAnd for triggeringstateThe updateddispatchMethods, etc.,The entire app has a single Store. Several managements are provided in the StorestateThe API:
    • store.getState(): Gets the current state
    • store.dispatch(action)Trigger:stateChange (the only way)
    • store.subscribe(listener)Set:stateA view update function that triggers automatic view rendering if passed in as a listener
  • Action: Like Flux, Action is the message object used to update state and is emitted by the View
    • There is an Action Creator that specifically generates actions, which is essentially a function that returns an Action object
  • Reducer: is a basisaction.typeupdatestateAnd returnnextStateReplace the originalstateA pure function of synchronization(Returns the same result for the same parameter, does not modify the parameter, does not depend on external variables). That is, the new state can be deduced by applying state and Action:(previousState, action) => newState.Reducer returns a new state

The overall process is as follows: Action Creator => Action => Store.dispatch (Action) => Reducer (state, Action) => State = nextState. The flow chart is as follows:

Middleware

Redux also supports middleware for managing asynchronous data flows.

Redux’s Middleware is a method that wraps store.dispatch() to make it pass functions other than actions or promises; ApplyMiddleware through the applyMiddleware method. (When the last middleware in the chain starts a dispatch action, the action must be a normal object.)

Common libraries: Redux-Actions, redux-thunk, redux-Promise.

const store = createStore(
  reducer,
  // Execute in sequence
  applyMiddleware(thunk, promise, logger)
)
Copy the code

The characteristics of the story

  • Unidirectional data flow. View emits Action (store.dispatch(action)), the Store called Reducer to calculate the new state, if the state changes, call the listening function to re-render the View (store.subscribe(render))
  • Single data source, only one Store
  • State is read-only and only one new state can be returned after each status update
  • Instead of a Dispatcher, the dispatch method is integrated into the Store, where store.dispatch() is the only way a View can issue an Action
  • Support for using Middleware to manage asynchronous data flows

Vuex

Vuex is the state management mode of Vue.

The core concept of Vuex

  • Store: Vuex uses a single state tree, and each application has only one Store instance, which includes state, Actions, Mutations, getters, modules
  • State: Vuex forSingle data source
    • Can be achieved bymapStateHelper functions access state as a computational property or are used after state is injected globally via Storethis.$store.stateaccess
    • The State update view is implemented through VUE’s bidirectional binding mechanism
  • Getters: Getters act somewhat like filters in that they filter out State
  • Mutation:Mutaion is the only way to change State in VUex(in strict mode) and can only be synchronized. Vuex throughstore.commit()Call the Mutation
  • Action: some to StateAsynchronous operationsYou can put it in an Action and change the state by submitting Mutaion on the Action
    • The Action bystore.dispatch()Methods the trigger
    • Can be achieved bymapActionsThe helper function maps the methods of the VUE component tostore.dispatchCall (need to inject store at the root node first)
  • Module: When the Store object is too large, it can be divided into multiple modules according to the specific business needs, each Module has its own state, mutation, action, and getter

Vuex features:

  • Unidirectional data flow. The View through thestore.dispatch()Call the Action and pass it after the Action has performed the asynchronous operationstore.commit()The view is updated through vUE’s reactive mechanism by calling Mutation to update State
  • Single data source, just like Redux, there is only one Store instance globally
  • Applies only to Vue

MobX

The philosophy behind MobX is:

Anything derived from the application state should be acquired automatically.

This means that when the state changes, all the places applied to the state are automatically updated.

Core concepts of MobX

  • State: data that drives the application
  • Computed values: Computed values. Use computed if you want to create a value based on the current state
  • Make eye contact: Reactions that occur when your state changes
  • Actions: Actions used to change State
  • Dependency Collection (autoRun) : Data in MobX is based on observer mode, adding observers through the autoRun method

Here’s an example:

const obj = observable({
  a: 1.b: 2
})

autoRun((a)= > {
  console.log(obj.a)
})

obj.b = 3 // Nothing happened
obj.a = 2 // The observe callback is triggered, and the console says: 2
Copy the code

The characteristics of MobX

  • Data flow does not flow naturally, only the data used will trigger binding, local precise update (fine-grained control)
  • There is no backtracking capability because the data is only one citation
  • Object-oriented based
  • Often multiple stores
  • Code is less intrusive
  • Simple scalability
  • Large projects using MobX can make code difficult to maintain

conclusion

  • Flux, Redux, and Vuex are unidirectional data flows
  • Redux and Vuex are Flux based. Redux is more general and Vuex can only be used for VUE
  • Flux and MobX can have multiple stores, while Redux and Vuex have only one Store globally (single state tree)
  • Redux and Vuex are suitable for state management of large projects, while MobX’s application in large projects makes code maintainability worse
  • Middleware was introduced in Redux to deal with the side effects of asynchrony and to do a lot of complex work through conventions
  • MobX is one of the least intrusive code in the state management library. It has fine-grained control, simplicity and extensibility, but no backtracking capability, and is generally suitable for small to medium sized projects

Reference:

  • www.ruanyifeng.com/blog/2016/0…
  • www.ruanyifeng.com/blog/2016/0…
  • zhuanlan.zhihu.com/p/53599723
  • vuex.vuejs.org/zh/
  • cn.redux.js.org/
  • cn.mobx.js.org/