This is the last article in the series on React state management.

The first few articles in the Nuggets were largely unread. Maybe it’s too long? Nuggets too low? Or too many typos? After I calm down and think about it, writing is a process of learning and accumulation for me, which enables me to learn to describe things in a more comprehensive and systematic way. But writing is really time-consuming. Every sentence in an article has to be carefully considered, and it has to be subjective so as not to mislead others.

So, in a parody of kernel Panic’s slogan: “If you want to see it, if you don’t, don’t watch it.”


Series directory

  • 01 Type Check
  • 02 Component organization
  • 03 Style management
  • 04 Component thinking
  • 05 Status Management


The article directories

  • State management
  • You don’t need state management
  • You don’t need complicated state management
  • Redux
  • Mobx
  • RxJS
  • Other status management schemes
  • Further reading




State management

One of the core ideas of current front-end frameworks, including React, is data-driven views, namely UI = F (state). This change in development is actually due to virtual-DOM, which allows us to care about ‘state’ and ‘state-to-UI mapping (F)’ rather than the operation details of the browser’s underlying DOM. So if you’re a beginner and don’t understand what ‘data driven’ is, it’s not recommended to continue reading the rest of this article.

However, with the complexity of state, the framework’s existing componentalization approach is difficult to control F (the mapping of views becomes complex and difficult to express and maintain); Or related types of application data flows are complicated and the interaction between components is diverse, so it is difficult to use UI = F (state) to express them. Or the application’s component states are too discrete, requiring uniform governance, and so on. We have the need for state management.

The most basic solution of state management is stratification, which means that there is no essential difference between the traditional MV* mode and the main structure of the mainstream state management is basically like this:

They all basically have these characteristics:

  • Separate view and stateState managers are good at state management, so they tend to manage application states together, and the view degenerates into an anaemic view (which only focuses on presentation), which can be simplifiedfMapping relationship, let’sUI = f(state)This expression is more thorough
  • Constraint state changes. Redux asked to passdispatch+reducerMobx requires data change functions to be usedactionTo decorate or place.flowFunction, the goal is to make state changes predictable
  • One-way data flow. The data flow always follows Store -> View -> Store, simplifying the data flow


React, however, has so many state management options that choosing between them can be maddening, and there are many trade-offs:

  • Object oriented or functional or functional responsive?
  • Single Store or multiple stores?
  • Immutable data or mutable data?
  • Is coding fun or post-maintenance fun?
  • Freedom or constraint?
  • Strong type or weak type?
  • Canonical data or uncanonical data?
  • React native or third party?
  • .




You don’t need state management

State management is not required for most simple applications and back-end projects. To be honest, these apps are no different from traditional Web pages. Each page is independent, and each time a new page is opened, the latest data is pulled, deleted, and checked. React component states are sufficient for these scenarios. There is no need for state management for the sake of state management. These separate ‘static’ pages, with state management, are overdesigned.

Before you consider introducing state management, consider whether any of these techniques can solve your problem:

  • Can communication between components be achieved by elevating State?
  • If there are too many levels across, can the data be shared through the Context API?
  • Can some global state be placed in localStorage or sessionStorage?
  • Can data be shared through an external event subscriber?
  • .




You don’t need complicated state management

Start thinking about state management when your application has the following scenarios:

  • State sharing is required between components. The same piece of data needs to respond to and be changed by multiple views
  • You need to maintain global states and respond to the view as they change
  • The React component can’t handle the complexity of the data flow. Examples include user collaboration across pages
  • Application status needs to be managed in a unified manner. Such as persistence, recovery, undo/redo
  • .

Do you need complex state management tools like Redux and Mobx? In 2019, many of these features will be replaced by features provided by React itself. With the release of the React 16.3 Context API, which makes it easy to do simple state management on top of it, we should prioritize these native state management methods.

For example: simply use the Context API for state management:

I wanted to do a state manager in conjunction with the Context API, but it was already done: unstated-next, 38 lines of hooks +Context, very simple interface:

Thanks to the flexible nature of hooks, we can do a lot with them, limited to imagination. For example, asynchronous data retrieval:

Or implement Redux’s core features:


To summarize the advantages of using hooks as state managers:

  • The minimalist. As above
  • composability.hooks are just plain functions that can combine other hooks, as well as othersHooks ContainerThe last article mentioned that hooks write like components. Components write like hooks, which are considered a ‘special’ kind of hooks in usage. Hooks have more flexible composition features than components
  • In the name of react. Component state sharing based on Context and state management based on hooks is general enough.
  • Hooks are flexible enough to replace much of the functionality of frameworks like Mobx
  • This is a normal React component that can be debugged in the React Inspector
  • Strongly typed
  • Easier modularity (or fractals) based on Context API


Something to watch out for

  • There is no external state. The state is inside the component, and there is no way to trigger state changes externally
  • Lack of constraints. Both advantages and disadvantages, for teams and beginners, lack of constraints will lead to disunity of style, unable to control the increase of project entropy. The advantage is that you can customize your own constraints
  • Performance optimization: Performance issues caused by Context changes need to be considered
  • The debugging experience is not as good as Redux
  • Without data mirroring, requirements such as event management cannot be implemented
  • Not as rich as Redux’s ecology

So Context+ Hooks can be used for simple state management needs, but for complex state management needs specialist state managers like Redux and Mobx are needed.


Other similar schemes

  • Unstated Unstated – The predecessor of Next, using the setState API
  • react-hooks-global-state

extension

  • React Context API — A Replacement for Redux?
  • Unstated: Probably the best simple state management tool out there



Redux

Unstated is a minimalist state management scheme. The author also said that we should not think of unstated as a Redux killer. We should not build complex tools on top of it, that is, we should not repeat the wheel. Redux, Mobx, Rxjs and other sophisticated state management frameworks should be considered at this point.

Redux is a framework that learning React can’t get around. Although Redux has only a hundred lines of code, it has a lot of concepts and a steep learning curve, as the official documentation shows. Even though its implementation is clean, developing code is not clean (as opposed to Mobx, where the dirty work is left to the developers), and especially following its’ best practices’, building a project from scratch can be tedious. There are secondary wrapper libraries like DVA or Rematch to simplify it.

This article is not intended to go into the details of Redux’s practices; there are plenty of tutorials available in the community, and the official documentation is quite thorough. This section introduces the main architecture and core ideas of Redux, as well as the scenarios where it is applicable.

The main structure of Redux is described above, but you need to understand why Redux is designed the way it is. In my opinion, Redux mainly aims to solve the following two problems:

  1. Predictable state
  2. Simplify application data flow


In fact, this is also the original intention of Flux, but there are some things it doesn’t do well. Knowing what Redux is all about, it’s much clearer to look at its design now

  • Single data source -> Predictable, simplified data flow: data can only be modified in one place

    • Simplifies application data flow. Solve the traditional multi-model model data flow chaos problem (such as one model can modify other models, a view is driven by multiple models), make data changes predictable and debuggable

    • Isomer application development

    • Convenient debugging

    • Convenient for data mirroring. Undo/redo, time travel, hot overload, state persistence, and recovery are possible

  • Unidirectional data flow -> Simplified data flow, predictable

  • Cannot change status directly -> predictable

    • State changes can only be triggered by a Dispatch action, which is a simple object that carries the event type and payload
    • Reducer receives actions and old states, and the reducer generates new states. Reducer is only a pure function and can nest a combination of reducer to reduce the complex state tree
    • Immutable data.
    • Can be tested.
  • Formalization and antiformalization. Store stores only conventional data to reduce data redundancy. The data required by the view is de-canonized by means such as ResELECT

  • The core concept of Redux is reducer, but this is a pure function. To achieve complex side effects, Redux provides a koA-like middleware mechanism to implement various side effects. In addition, middleware mechanisms can be utilized to implement common business patterns and reduce code duplication.

  • Devtool -> predictable. Data flow can be visualized through developer tools


When should YOU use Redux?

A word of warning: You Might Not Need Redux, Redux is Not your first choice.

When we need to deal with complex application states and React itself doesn’t work for you. Such as:

  • You need to persist the application state so that you can recover the application from local storage or data returned from the server
  • Undo redo needs to be implemented
  • Implement user collaboration across pages
  • When the application state is complex
  • Data flow is complex
  • Many unrelated components need to share and update state
  • State of the outer
  • .


Best practices

Personally, THE React-Boilerplate is the project template that most closely conforms to the official ‘best practice’. Its application workflow is as follows:

Features:

  1. Integrating popular solutions from Redux Ecology:immer(immutable data changes),redux-saga(asynchronous data stream processing),reselect(Select and map state, support memo, can be composite),connected-react-router(Bind react-Router V4)
  2. Split saga and Reducer according to the page. See 👇 and directory structure below
  3. Load Saga and Reducer as needed (via replaceReducer)
  4. Divide container components and presentation components

Look again at the React-Boilerplate directory structure. This is my personal favorite component approach to the project, which is very clear and referential

Containers # 🔴 containers/pages /App # root components, For example, place Provider and Router /HomePage # page components index.js # page entry constants.js # 🔴 Here to define various constants. Include Action Type actions.js # 🔴 define various Action functions saga.js # 🔴 redux-saga define various saga methods used to handle asynchronous flow reducer. Both reducer and saga of page components are injected as needed into the root store selectors # 🔴 redux state mapping and calculation message.js form.js # various local components input.js... FeaturePage # FeaturePage SagaInjectors. Js # 🔴saga injector, I18n. js # i18n configureStore.js # 🔴 Create and configure Redux Store reducers.js # 🔴 root reducers, Merge all 'page states' and' global states '(e.g. Router, language, global(e.g. User authentication information))Copy the code


🤬 start teasing!


  • First, the core library of Redux is small and only provides dispatch and reducer mechanisms. Redux provides middleware mechanisms to outsource all kinds of complicated side effects. Redux-promise, Redux-Saga, Redux-Observable… Check out Redux’s ecosystem.

    The benefit of Redux middleware is that it is very scalable and can be used by developers to abstract repetitive business. The middleware ecosystem is also flourishing, but it is not friendly to beginners.

    TM at least needs to know about the various libraries and do a horizontal comparison to know which library he needs to match. Ok, redux-saga is the most popular star. Don’t program for star. Choose what suits your team. So before you pick the right one, you still have to know the options themselves, right? .

    That’s why Vue’s learning curve is so flat. It helps us make a lot of choices, provides concise solutions, and provides style guides and best practices. These options fit more than 80% of your development needs. Developers spend a lot less time messing around and can focus on writing their business. This is the so-called ‘progressive’ framework, for those who do not bother or beginners, we help you choose, but will not hinder you to go to the advanced place. The React and Vue communities are completely different in style.

    When you have a choice problem, look at other people’s choices, such as influential teams or popular open source projects (such as DVA and Rematch), pick a compromise, and explore it later. A popular combination for Redux at the moment is immer+ Saga + Reselect


  • Two, too much template code. For example, the above react-Boilerplate involves five files and needs to define various Action types, actions, Reducer, Saga and Select. So even a small state change requires several changes:

    The author personally prefers the organization mode similar to The Ducks style of Vuex, and organizes the action, saga, Reducer and mapper under the module into one file:

    Redux’s repackaging framework basically follows a similar style, such as Rematch

    These secondary packaging frameworks generally do the following optimizations (which can be considered a Vuex advantage) to improve the Redux development experience:

    • Organize code using Ducks style. Assemble fragmented Reducer, saga, actions…
    • More simplified APIS
    • Provides an easy-to-use modularity (or ‘fractals’) or namespace mechanism. The module itself supports’ state isolation ‘, allowing the Reducer and saga of the module to focus only on the state of the module. Dynamic loading is also considered in the module
    • Built-in side effects handling mechanism. Use saga or Redux-Promise
    • Simplifies the operation of immutable data. If use immer
    • Simplify the reducer. CombineReducers are built into Redux to combine multiple reducer. Inside Reducer, we generally use switch statements to receive actions and deal with data changes, which is actually very verbose. Vuex, like these encapsulation frameworks, uses the key/value form for greater clarity
    • Simplify the CONNECT interface at the View layer. Such as simplified mapProps, mapDispatch these codes are also cumbersome to write


  • Third, forced immutable data. As mentioned in the previous article, setState is verbose. The easiest way to ensure state immutability is to use the object expansion or array expansion operators. More complicated ones can be Immutable. Fortunately, immer is now available to implement immutable data in accordance with Javascript’s object manipulation conventions


  • Fourth, state design.

    Data types are generally divided into Domain data and application data (or UI data). When using Redux, you often need to consider whether state should be placed locally in the component, or whether all state should be extracted to the Redux Store. It’s more of a hassle to put that data in the Redux Store, right? Now that you’re using Redux, is it against best practice not to extract data to the Redux Store? I often wonder if you are a victim of best practices.

    I think it can be considered from the following points:

    • Domain data or application data? Domain data is generally recommended to be stored in the ReduxStore, which is often thought of as a database for stylized data.
    • Is state shared by multiple components or across pages? The Redux Store is a global state Store, and since Redux is in use, it makes sense to have Redux manage state across multiple components
    • Does the state need to be mirrored? If your app is going to ‘time travel (undo/redo)’ or persist your app, and this state needs to be restored, it should be in the Redux Store, where centralized management of data is Redux’s strong suit
    • Does the state need to span the life cycle of the component? Put the state in the component part and it will be destroyed along with the component. If you want the state to span the lifecycle of the component, you should put it in the parent component or in the Redux Store. For example, whether data edited by a modal box needs to be preserved after it is closed

    The principle is to put what can be put locally. Choosing between local and global state requires a little development experience.

    In addition, as a centralized state manager, it takes some effort to design the state structure for readability (easier to understand) and operability (easier to add, delete, and change). The design approach for the database structure is the same. Before designing the state, you need to understand the relationship between the various domain objects and balance the complexity/performance of data retrieval and data change operations.

    Redux officially recommends formalizing State, flattening structure tree, reducing nesting and reducing data redundancy. This tends to be easier to update and store, leaving it to libraries like ResELECT to calculate, map and combine what the view needs.

    So Redux isn’t that simple, and 80% of Web applications don’t have to be either.


  • Fifth, inconvenient Typescript typing. Neither Redux nor the secondary wrapping framework is particularly convenient for Typescript type derivation, especially with the addition of extensions. You may need to explicitly annotate many data types

    Extensions: React-redux-typescript -guide, rematch & typescript

  • Sixth, it is not a Fractal.

    I don’t know what fractals are until I see @Yang Jianfeng’s answer. I can only try to explain my understanding of fractals:

    The “separate logic and view” and “separate container components and presentation components” rules mentioned in the previous article are derived from Redux best practices. Redux is a ‘non-fractal architecture’, as shown below. In this simple ‘horizontal layering’, views and logic (or state) can be reused individually, but in Redux it is difficult to reuse both as integral components:

    A centralized Store with a Connect mechanism that allows state to be reused across the entire application; The state and behavior of the Dumb component being removed are also easy to reuse

    Now suppose you need to separate a single container into a separate application. A single container does not work independently. In the fractal architecture, an ‘application’ is composed of smaller ‘applications’, which have their own internal state mechanism. A single application can work independently or as a sub-application. For example, Elm, the ancestor of Redux:

    The Store structure is the same as the application structure. Each Elm component is a Elm application, complete with Action, Update, Model, and View. Allowing individual applications to be reused

    Redux is not a fractal and Redux itself is positioned as a pure state manager that does not involve component view implementation, so it cannot form a complete application loop like ELM and CycleJS. In fact, you can see that the React component itself is fractal. The component is originally a collection of states and views.

    The benefits of fractals are more flexible reuse and composition and less glue code. Obviously, frameworks that support pure fractal architectures are not popular right now, probably because the bar is high. In my opinion, not supporting fractals is not a pain point for Redux in engineering. We can split Redux into multiple modules through “modularization” and maintain them independently in multiple containers. Is it fractals to some extent? This horizontal separation of UI and state also has advantages, such as the UI changing more frequently than the state of the business.

    Personally feel page this level of differentiation is just right, such as convenient division of labor. For example, I recently had a project where we needed to convert a native Windows client into a electron implementation. Limited by resources, this project involved collaboration between two teams. For this project, the App Store is an interface layer, where the Windows team maintains state and implements business logic, and our front end team takes care of the presentation layer. This way Windows doesn’t need to learn React and view presentation, and we don’t need to relate their complex business logic (using C++ at the bottom, exposing part of the interface to node).


Seven, there may be performance issues

  • Redux FAQ: Performance
  • Is the state tree in Redux too large to be a performance problem?
  • Why did I move from Redux to Mobx
  • Mobx vs. Redux performance


conclusion

This section focuses on the motivation for Redux design and the series of designs around that motivation, as well as some of Redux’s shortcomings and best practices. Redux has a thriving ecosystem, and if you are a beginner or don’t want to mess around, it is recommended to use secondary packaging frameworks such as Dva or Rematch, which are often a repository of some of Redux’s best practices and reduce the amount of time it takes to mess around. Of course this is just the beginning, you still have a lot to learn about organizing a large project.


Further reading

  • What’s wrong with Redux
  • Pain points, analysis and improvement of Redux state management
  • What are the best practices for Redux?
  • How to evaluate the Data Flow management architecture Redux?
  • Is there anything else that Redux should do in 2018?
  • Cycle.js state management model
  • Develop complex spAs using Dva
  • Redesigning Redux
  • Redux official documentation
  • Redux triple condition




Mobx

Mobx provides a vUe-like responsive system with an architecture that is easier to understand than Redux’s. Take the official picture:

  • Reactive data. First, use @Observable to convert data into ‘reactive data’, similar to Vue data. Dependencies can be collected when the data is accessed in some context (such as computed, the React component of the Observer wrapper, and Reaction), and dependencies are notified when the data changes.

    Two advantages of reactive data are: (1) simplified data manipulation (compared to REdux and setState); (2) Accurate data binding. Views need to be rendered only when the data actually changes. The smaller the granularity of component dependencies, the finer the views can be updated

  • Derivative.

    • Derived data. Mobx also recommends not putting redundant or deducible data in the state, but using@computedComputation-derived states. Computed is a concept similar to ResELECT in Redux, which computs formalized data in an antiformalized or aggregated manner
    • Side effects spawn. Side effects that depend on data are triggered when the data changes, including ‘views’. A view is a mapping of reactive data
  • Mobx recommends that data be changed in action/flow(asynchronous operations). Action is a combination of Dispatch and Reducer in Redux. Mobx limits changes to action functions in strict mode, which makes state changes traceable. It is recommended to isolate side effects in flow functions, which are similar to Redux-Saga, with asynchronous operations and side effects isolation via generators


This is the core concept of Mobx. Here’s a simple example:

But Mobx is not a framework, it doesn’t tell you how to organize code, where to store state, or how to handle events like Redux does, and there are no best practices. The advantage is that you can organize component projects according to your preferences, such as Redux(Vuex), or in an object-oriented way. The downside is if you don’t have the experience, you don’t know how to organize code, right

Mobx generally uses an object-oriented approach to Store organization, as described in the official documentation on best practices for building large, scalable and maintainable projects, which is the classic MV* pattern:

SRC/components/ # display component models/ # 🔴 place some domain objects order.ts user.ts product.ts... Stores / # store AppStore. Ts # Store store auth, language, theme OrderStore. Ts # store Containers/App/ # root component Orders/ # page component... Utils/store.ts # store initializes index.tsxCopy the code


Domain object

There are too many nouns and concepts in the object-oriented world, and they are abstract. Leaving aside the theoretical domain of what an object is, think of it as an OOP abstraction of a real-world business entity. Specifically, you can think of it as M in the MVC pattern, or as an object mapped from a database in an ORM.

For complex domain objects, they are extracted as separate classes, such as the Todo class in the previous example. The advantage of extraction as classes is that they are encapsulated and can contain associated behaviors, definitions and associations with other objects, which is more expressive than pure objects. The downside is that it’s hard to serialize

Because they are weakly associated with the page and can be reused across multiple pages, they are placed under models/ in the root directory. At the code level domain objects have the following characteristics:

  • It defines fields (@Observable) and operations on domain objects (@Action), and may be associated with other domain objects, such as orders associated with users and products
  • The Store manages the life cycle, or the Store is the container for the Model, which is the database. Stores are also usually singletons

The sample

import { observable } from 'mobx';

export default class Order {
  public id: string;

  @observable
  public name: string;

  @observable
  public createdDate: Date;

  @observable
  public product: Product;

  @observable
  public user: User;
}
Copy the code


Store

The Store is simply a Model container that manages the life cycle of Model objects, defines derived states, encapsulates side effects, integrates with back-end interfaces, and so on. Stores are generally singletons. Mobx apps are typically divided into multiple store-bound pages.

The sample

import { observable, computed, reaction } from 'mobx';

export default class OrderStore {
    // Define model state
  @observable orders: Order[] = [];

  _unSubscribeOrderChange: Function
  rootStore: RootStore

  // Define derived data
  @computed get finishedOrderCount() {}
  @computed get finishedOrders() {}

  // Define side effects derived
  subscribeOrderChange() {      this._unSubscribeOrderChange = this.orders.observe((changeData) = >{}}/ / define the action
  @action  addOrder (order) {}
  @action  removeOrder (order) {}

  // Or some asynchronous action
  async fetchOrders () {
    const orders = await fetchOrders()
    orders.forEach(item= > this.addOrder(new OrderModel(this, item)))
  }

  // Initialize, initialize data structures, initialize subscriptions, etc
  initialize () {
    this.subscribeOrderChange()
  }

  // Some cleaning up
  release () {
    this._unSubscribeOrderChange()
  }

  constructor(store: RootStore) {
    // Communicate with rootStore
    this.rootStore = store
  }
}
Copy the code

Root Store

class RootStore {
  constructor() {
    this.appStore = new AppStore(this);
    this.orderStore = new OrderStore(this); . }}Copy the code
<Provider rootStore={new RootStore()}>
  <App />
</Provider>
Copy the code

Look at a real world example

This traditional MVC organization has the following advantages:

  • Easy to understand, easy to start with. The classic MVC pattern, object-oriented, we are all too familiar with. This is especially true for back-end developers who are familiar with traditional object-oriented programming paradigms such as Java. For the cross-team project mentioned above, we chose Mobx as the state manager, which is the best way for them to understand. However, a bit of experience is required in the separation and design of domain objects and domain stores
  • Strongly typed
  • Clean code. In contrast to Redux’s redundant template code
  • Data encapsulation. Data structures expressed using classes can encapsulate the corresponding behavior

The problem

  • Sharing data between multiple stores is cumbersome. Our approach is to have all stores inherit a parent class as an intermediary that communicates data between stores through an event subscription model
  • Lack of organization. Compared to Redux, the state is too fragmented to be constrained and can be modified at will. A lot of our code does that, not bothering to write actions and even assigning states directly in the view layer. So be sure to start in strict mode
  • No Magic. This is a double-edged sword, Redux has middleware mechanisms that can extend and abstract many repetitive tasks, such as loading state for asynchronous methods, but are not Typescript friendly; Class-based solutions, nowhere to start, the code will be more verbose, but more intuitive
  • There is no data snapshot, so you can’t go back in time, which is Redux’s strong point, but most applications don’t need this feature; Alternatively, mobx-state-tree can be implemented
  • Not hot – reload


There are also some problems with MOBx itself, which were discussed in the previous article, as well as in this article:

  • The React component structure needs to be changed. For example, all components that need to respond to data changes need to use the Observer decorator. Component local state also requires observable decorations, data manipulation, and so on. The mobx coupling is deep and the cost of switching frameworks or refactoring later is high

  • Compatibility: Proxy was used for refactoring after mobx v5, but Proxy was not supported until Chrome49. You can only use V4 if you want to be compatible with older browsers, and V4 has some pits that are hard to spot for newcomers to Mobx:

    • The Observable array is not really an array. Antd’s Table component, for example, does not recognize mobx’s array and needs to be passed in to components for conversion using slice
    • Adding properties to an existing Observable is not automatically captured


MV* is just one of the main ways Mobx is organized, and many articles discussing Redux and Mobx tend to descend into a functional versus object-oriented debate and conclude that Redux is better for large projects, The main reason for this conclusion is that Redux is more constrained (only one way to do it), suitable for project evolution and team collaboration, rather than functional and object-oriented. Of course, both functional and object-oriented paradigms have areas of expertise, such as functional for data processing and complex data flow abstractions, and object-oriented for business model abstractions, so don’t just write them off.

In other words, suitability for large projects is a project organization issue, and Mobx didn’t come up with any early solutions and best practices. Later, the author also developed mobx-State-Tree, which is an official state model building library provided by MOBx. MST absorbs the advantages of Redux and other tools. The goal is to combine transactionality, traceability and composition with mutable data/object orientation. Co-location and Encapsulation), Provides useful features such as data mirroring (Time Travel), Hot Reload, Action Middleware, integrated Redux-DevTools, and strong typing (Typescript + runtime checking), It’s more like a back-end ORM tool like ActiveRecord that builds an object graph.

Typical code:

Due to the author’s limited practice of MST, and the length of the article is very long, so I will not expand on it, and I will share it later when I have the opportunity.


Still have to make a decision, Mobx or Redux? The results of MobX vs Redux: Comparing the Undefined Paradigms-React Conf 2017:

  • Small teams that need to develop simple applications quickly can consider using MobX because of its small amount of code to develop, low cost of learning, and speed of learning. MobX is suitable for real-time systems, dashboards, text editors, and presentation software, but not for event-based systems
  • Redux is ideal for large teams developing complex applications. Redux is scalable and maintainable to withstand multiple collaborations and business needs, and is suitable for commercial systems, event-based systems, and game scenarios involving complex reactions.

The main basis for this conclusion is that Redux reacts to actions/events and MobX reacts to state changes. For example, when a data change involves multiple Mobx stores, Redux’s approach is more elegant and the data flow is clearer. The advantages and disadvantages of Mobx and Redux have been explained in detail in the previous section. Mobx and MST also have advantages and disadvantages


extension

  • Do you need Mobx or Redux?
  • The realization principle of Mobx idea, and comparison with Redux
  • MobX vs Redux: Comparing the Undefined Paradigms-React Conf 2017 Notes
  • Dob is lighter with mobx-like wheels
  • React state management solution used at the front end of jemeng: Rex
  • Dry goods | Mvvm earnestly the front-end data flow framework

RxJS

If none of the state management tools mentioned above are adequate for your needs, your project is probably more complex than 99% of all projects in the country. RxJS is very suitable for complex asynchronous event flow applications. I don’t have much practice in this area. I recommend reading xu Fei’s article




Other status management schemes

  • Apollo+GraphQL
  • freactal

State of React State Management for 2019




Further reading

  • Exploration of data flow schemes for single page applications
  • Data layer design for complex single-page applications
  • State of React State Management for 2019
  • The Design error of state management from time travel utopia