State management is a concept that the front end encounters all day long, but have you ever thought about what is state and what is management?
We know that the program processes data, and data is the carrier of information, such as red or blue color is data.
So why not call it data management? What is the relationship between state and data?
The state is the change of the data, such as the color is red or blue is the data, and the color changes from red to blue.
The change of state corresponds to the rendering of the view or the execution of a piece of logic. For example, changing the color from red to blue may require re-rendering the view and executing the logic of sending the request to the server.
Triggering changes in state through view interaction or other means, state changes link the rendering of the view and the execution of logic, which is the core of the front-end application.
Why didn’t you hear about the concept of state management in the jQuery era, but often heard in the Vue and React eras?
The jQuery era is to manually render the data to the view and execute the logic after the data change, it may not have a clear state of this layer, but directly render the data into a dom, the next time you need data is also taken from the dom.
In the era of Vue and React front-end frameworks, there is no need to manually operate dom and execute the logic after data changes, as long as the state is managed, the front-end framework is responsible for the processing after the state changes.
What does state management manage?
What is state management
There are two specific meanings of state management:
For example, React’s setState will not immediately modify the state, but will be executed asynchronously in batches to merge the states.
For example, Redux’s action also undergoes middleware processing before modifying the global state.
These are the management of asynchronous processes before state changes and are the first layer of meaning of state management.
For example, if React setState modifies the state to trigger the rendering of the view and the execution of the lifecycle function, the hooks are also re-executed after the state of the dependent array changes. (vue’s data modification re-renders the view, executes computed and watch logic)
After Redux modifies the global state, it tells the component to do rendering or other logical processing, such as Vuex, Mobx, etc.
These are the management of linkage processing after state changes, which is the second layer of state management.
We know what is state and what is state management, so how do the front-end frameworks Vue, React and the global state management libraries Redux, Mobx, and Vuex implement state management?
Two implementation ideas for state management
The state will not be one, and the collection of multiple states will be represented by the key and value of the object, such as the state object of React, the data object of Vue (although it is called data also refers to the state).
How do you listen for changes in an object?
Can we provide an API to modify, do the processing before the state change within this API, and do the linkage processing after the state change.
Such a scenario can only trigger state modification through APIs, and directly modifying state cannot trigger state management logic.
React’s setState is this idea, through the setState modification of the state will do a batch of asynchronous state merging before the state change, will trigger the state after the state change and the view rendering and hooks, life cycle re-execution. But it is useless to modify the state directly.
So how can you directly modify the state and monitor the change?
You can do a layer of proxy on the state object, proxy its get, set, when the execution of the state get to collect the logic dependent on the state, when the set modifies the state to notify all the logic dependent on it (view rendering, logic execution) to update.
Vue’s data listening changes are based on this idea, encapsulating dependencies as Watchers when the state gets and notifying all Watchers to make updates when set.
This idea is called reactive, which is the meaning of automatically responding to changes after the state changes.
The proxy get, set can use the APIs of Object.defineProperty, but it cannot listen for dynamically added or deleted object properties, so Vue3 is implemented with the proxy API.
The changes in the listening object are in these two ways:
However, frequent modifications to the state do not have to do linkage processing every time, some can be combined, such as changing the color to red twice, then the subsequent logic does not need to be executed twice, and some performance optimization needs to be done.
So React’s setState is asynchronous and will do batch state merging (note that React’s setState is not passing in the final state, but the diff state that React is going to update to the state).
And Vue because it is the same object directly modified, so there is no need to do any merge, its Watcher execution is asynchronous, and the Watcher that is put into the queue many times can be heavy.
This is the case with state management within components, which utilizes the state mechanism that comes with the front-end framework.
What about between components? How does the state of one component change in conjunction with other component changes?
However, props can only be passed layer by layer, and if the component and the component that wants to link the change are separated by many layers, it is very troublesome to pass the props.
In this case, the front-end framework also provides solutions, React provides Context, and Vue provides Event Bus.
React components can hold state in the context and directly trigger the rendering of the associated component when the state in the context changes.
Vue can emit one event within a component, then another component on this event, and then update its own data to trigger rendering. However, both APIs were discarded in Vue3.
This kind of front-end framework comes with any layer of components of the state linkage scheme can only handle simple scenes, complex scenes still have to use the global state management library, such as Redux, Vuex, Mobx and so on.
Remember the two layers of state management? Management of asynchronous processes before state changes, linkage processing after state changes.
Both Context and Event Bus only do the linkage processing after the state change, but do not support the asynchronous process management before the state change.
For example, multiple components have to modify the value in the context (or modify the global state through the event bus), this process must execute a period of asynchronous logic, to do loading display, then how to reuse this loading logic in multiple components?
Also, if the asynchronous process is more troublesome and you need to use a library like rxjs, how can you combine the context and event bus scheme with rxjs?
Of course, it is possible to do some logical multiplexing of the context and event bus and some packages that combine rxjs schemes, but it is more troublesome.
And more importantly, if you want to do this, then there is no need to use context and event bus, just use the global state management library.
Redux provides a middleware mechanism, the component sends the action to the store (where the global state is stored), before going through layers of middleware processing, here you can do some reusable logic encapsulation, such as loading processing, can also be combined with rxjs this asynchronous process processing scheme.
The most commonly used middleware in redux is redux-saga and redux-observable, both of which manage asynchronous processes.
Redux-saga is based on the generator implementation, whether synchronous or asynchronous, as long as the declarative description of the logic to be executed, by the saga internal executors will do synchronous or asynchronous processing, the description of asynchronous logic is very concise, and redux-saga provides a lot of built-in logic encapsulation.
Redux-observable is a scheme that combines rxjs, turning action into a data source, going through layers of opreator processing, and finally passing to the store. You can use a large number of oprators in the rxjs ecology, do the assembly on the line, and do not need to write the specific implementation of asynchronous logic yourself.
mobx does not provide a middleware mechanism, its action is to execute a method of the status of the class, which can be encapsulated by the set of classes.
Some students are not familiar with these state management libraries, so let’s briefly introduce them.
We have clarified that there are only two implementations of state management, one is to provide APIs to make modifications, and the other is to make a responsive proxy for the state object.
This is true of the state management of the front-end framework, as well as of the stand-alone global state management library.
Redux is a scheme that provides APIs to modify, and uses the reducer function to process the incoming action and return a new state.
And the idea of redux is a functional idea, each reducer is a pure function corresponding to the input and output, the returned state is brand new, in order to facilitate the creation of a new state, it will generally be paired with the immutable library, as long as the property is modified will return a new state object.
mobx is a reactive proxy scheme that makes a layer of proxy on the global state (via Object.defineProperty), where the state’s get collects dependencies and triggers dependency updates when set.
Therefore, this scheme can naturally organize the global state into classes, which is an object-oriented idea, and can achieve logical reuse through inheritance and other ways.
vuex is like a combination of two ideas, internally using a responsive proxy to implement change monitoring, but the exposed api is the action set of redux.
If used with React, you need to add the component to the state dependency, which does not need to call APIs such as subscribe yourself, but directly use some packaged high-order components (components that accept the component as parameters to return the new component), such as react-redux’s connect, mobx-react’s observer.
Having said so much, a look back reveals that:
Whether it is the built-in in-component state change management scheme of the front-end framework (react’s setState, vue’s direct modification data), or the state-management scheme between components provided by the front-end framework (props, react context, vue’s event bus), or the third-party global state management scheme (redux, vuex, mobx, etc.), there is no separation from the two ways to implement state management: providing modified state APIs or a layer of responsive proxies to state objects.
There are also two meanings of separation from state management: managing the asynchronous process before the state change, and doing linkage processing after the state change. It’s just that they are used in different places (within the front-end framework, global state management library), provide different encapsulation forms (objects, functions), and combine different asynchronous management schemes (rxjs, generators + custom executors) based on different ideas (functional styles, object-oriented).
So, the state is the change of the data. The core problem of front-end applications is to manage the state, manage the asynchronous process triggered by the view or other means before the state change, and manage the linkage rendering and logical execution of the linkage after the state change.
Although we will use different front-end frameworks, different global state management libraries, and different asynchronous process processing schemes, the idea is the same.
It is no exaggeration to say that understanding state management is understanding the core of front-end development.
– EOF –
Add homepage Jun WeChat, not only front-end skills +1
Homepage Jun will also share front-end development learning resources and technical article selection on personal WeChat, and share some interesting activities, job promotion and how to use technology to do amateur projects from time to time
Add a WeChat and open a window
1. Take Vuex as a guide to get a glimpse of the overall situation management
2, SSR and front-end compilation, in this regard, is the same
3. This article analyzes Pinia and Vuex to take you to fully understand the two Vue state management modes
Think this article helped you? Please share it with more people
It is recommended to pay attention to the “Front-end Encyclopedia” to improve front-end skills
Likes and looks are the biggest support ❤️