What is the front-end state management?

Development side technology almost two years ago in full swing, a lot of front-end items are in use or turning Vue and React camp from the front page of one-page rendering applications accounted for higher and higher, which represents the front end of the complexity of the work also straight up, the information displayed on the front page more and more and more complex. We know that any state need to be managed, so today let's talk about the front end of state management.

Why state management?

for example:

Management of the library, the original is open, everyone has free access to library book stacks, if the number of small, this approach can reduce the flow, increase efficiency, the number increases once it is bound to cause confusion.

Flux idea is like the library to add an administrator (what is the thinking behind the flux would say), all library book commissioned by the behavior requires an administrator to do it, the administrator will standardize the operational behavior of the stacks It will record each person's operation, to reduce the phenomenon of chaos.

A metaphor:

We are sending a thing of the process

Without Express: packed and ready to send out the stuff directly to a friend's house, put things directly to friends very easily, very time-consuming

With Express: Package ready to send out something to the courier company, fill in items, basic information such as the recipient courier company for you to send articles to your friend's house, our job is over.

More than a courier company, courier company sent us the courier. When we only send articles to a friend, less frequently, and fewer items, we go directly to a friend's house just fine. But when we want to send to a lot of friends frequently when many commodities, the problem is complicated.

That is the essence of software engineering management complexity. The use of state management framework there will be some kind of learning costs and will usually do the simple things complicated, but if we want to do more complicated things (at the same time send a lot of different items to multiple addresses), for us, the courier will complex things become simple.

This also explains, if you need to add state management framework, we can add the actual situation according to their business and technical team preferences, in some cases, to create a global object will be able to solve many problems.

At work multiple states mutually binding scenario also find many, we can look at the major electricity supplier shopping cart settlement page, including all fixed takeaway shopping cart page. The main complication is that the multi-service status (such as commodity status, store coupons and combination packages, etc.), cross-linked multi-state level or position (check Cart, is checked first request to obtain the latest commodity price, status, etc., and then calculate prices and other above and below show the total price, etc.). As the different operations in different parts of the code data and in response to different logic.

How to solve the problem of multi-state between pages?

In the Web application development, AngularJS played an important role. However, two-way data binding AngularJS dirty and view-based detection mechanism, there is a short board performance, will change any data redraw the whole view. However, the reaction from the state view, is an advanced automatic page update thinking, in order to solve performance problems, Facebook's engineers have proposed the idea of ​​Virtual DOM. The DOM into memory, when the state changes, according to the state to generate a new Virtual DOM, then it and the previous Virtual DOM by comparing a diff algorithm, will be changed content rendering in the browser, avoiding JS engine frequently called DOM user interface rendering engine takes full advantage of the performance of JS engine. With Virtual DOM support, React born.

With React, "state => view" and will have a good idea of ​​the practice, but the reverse does, how rationally modified in view of the state has become a new problem, to this end, Facebook put forward Flux thought.

Yes, Flux is not a name of a JS library, but a framework for thinking, a lot of JS library is the realization of this idea, such as Alt, Fluxible, etc., which is used to build client Web application, specification data in Web applications the flow pattern.

Then the state management and what does it matter? We know, React Vue or just a library view layer does not have any restrictions on the data layer, may exist in other words the data layer code changes in any view of the components, and data layer for the excessive decentralization of management is unfavorable, in addition there is a problem once the data layer will be difficult to trace, because they do not know which components change is initiated from. Further, if the data is transmitted to the parent sub-assembly from the component by way of props, it will be a coupling between components, contrary to the principle of modularity.

Flux is the way of thinking of the way, to modify previously decentralization of the various components of the data layer controller code reverted to a unified management, the components need to be modified if the data layer needs to trigger a specific predefined dispatcher, then the dispatcher the action applied to the model, the data layer is modified to achieve. Then modify the data layer may be applied to the view, a unidirectional data flow is formed.

Flux realize ideas

Flux realize there are many different implementations also have highlights, here are some of the more popular realization of Flux.

Flux

This should be a more official "achieve Flux, seems quite satisfactory to achieve Flux architecture documentation of the basic concepts. It is the core Dispatcher, by Dispatcher, users can register requires appropriate action type, registered for different action corresponding callbacks, and trigger action and pass the payload data.

Redux

Redux actually equivalent to Reduce + Flux, and Flux same, Redux you need to maintain the performance of a data state of the application layer, but is different in that the data is not allowed Redux layer is modified, only by you need to describe an Action make changes. In Redux, the removed Dispatcher, instead use a pure function instead, this function receives the original pure state tree and the action as a parameter, and generates a new state tree instead of the original. And this so-called pure function, is an important concept in the Redux - Reducer.

在函数式编程中,Reduce 操作的意思是通过遍历一个集合中的元素并依 次将前一次的运算结果代入下一次运算,并得到最终的产物,在 Redux 中, reducer 通过合并计算旧 state 和 action 并得到一个新 state 则反映了 这样的过程。

因此,Redux 和 Flux 的第二个区别则是 Redux 不会修改任何一个 state, 而是用新生成的 state 去代替旧的。这实际上是应用了不可变数据 (Immutable Data),在 reducer 中直接修改原 state 是被禁止的, Facebook 的 Immutable 库可以帮助你使用不可变数据,例如构建一个可 以在 Redux 中使用的 Store。

下面是一个用 Redux 构建应用的状态管理的示例:

const { List } = require('immutable')
const initialState = {
    books: List([])
}
import { createStore } from 'redux'

// action
const addBook = (book) => {
    return {
        type: ADD_BOOK,
        book
    }
}

// reducer
const books = (state = initialState, action) => {
    switch (action.type) {
        case ADD_BOOK:
        return Object.assign({}, state, {
            books: state.books.push(action.book)
        })
    }
    return state
}

// store
const bookStore = createStore(books, initialState)

// dispatching action
store.dispatch(addBook({/* new book */}))

Redux 的工作方式遵循了严格的单向数据流原则,从上面的代码示例中可 以看出,整个生命周期分为:

在 store 中调用 dispatch,并传入 action 对象。action 对象是一个描述 变化的普通对象,在示例中,它由一个 creator 函数生成。

接下来,store 会调用注册 store 时传入的 reducer 函数,并将当前的 state 和 action 作为参数传入,在 reducer 中,通过计算得到新的 state并返回。 store 将 reducer 生成的新 state 树保存下来,然后就可以用新的 state 去生成新的视图,这一步可以借助一些库的帮助,例如官方推荐的 React Redux。

如果一个应用规模比较大的话,可能会面临 reducer 过大的问题。这时候 我们可以对 reducer 进行拆分,例如使用 combineReducers,将多个 reducer 作为参数传入,生成新的 reducer。当触发一个 action 的时候, 新 reducer 会触发原有的多个 reducer:

const book(state = [], action) => {
    // ...
    return newState
}
const author(state = {}, action) => {
    // ...
    return newState
}
const reducer = combineReducers({ book, author })

关于 Redux 的更多用法,可以仔细阅读文档,这里就不多介绍了。

Vuex

中国前端业务中使用 Vue 的比例是最高的,说到 Vue 中的状态管理就不 得不提到 Vuex。Vuex 也是基于 Flux 思想的产品,所以在某种意义上它 和 Redux 很像,但又有不同,下面通过 Vuex 和 Redux 的对比来看看 Vuex 有什么区别。

首先,和 Redux 中使用不可变数据来表示 state 不同,Vuex 中没有 reducer 来生成全新的 state 来替换旧的 state,Vuex 中的 state 是可以 被修改的。这么做的原因和 Vue 的运行机制有关系,Vue 基于 ES5 中的 getter/setter 来实现视图和数据的双向绑定,因此 Vuex 中 state 的变更 可以通过 setter 通知到视图中对应的指令来实现视图更新。

另外,在 Vuex 中也可以记录每次 state 改变的具体内容,state 的变更可 被记录与追踪。例如 Vue 的官方调试工具中就集成了 Vuex 的调试工具, 使用起来和 Redux 的调试工具很相似,都可以根据某次变更的 state 记 录实现视图快照。

上面说到,Vuex 中的 state 是可修改的,而修改 state 的方式不是通过 actions,而是通过 mutations。一个 mutation 是由一个 type 和与其对应 的 handler 构成的,type 是一个字符串类型用以作为 key 去识别具体的 某个 mutation,handler 则是对 state 实际进行变更的函数。

// store
const store = {
    books: []
}
// mutations
const mutations = {
    [ADD_BOOKS](state, book) {
        state.books.push(book)
    }
}

那么 action 呢?Vuex 中的 action 也是 store 的组成部分,它可以被看 成是连接视图与 state 的桥梁,它会被视图调用,并由它来调用 mutation handler,向 mutation 传入 payload。

这时问题来了,Vuex 中为什么要增加 action 这一层呢,是多此一举吗?

Vuex 核心的概念——mutation 必须是同步函数,而 action 可以包含任意的异步操作。 回到这个问题本身,如果在视图中不进行异步操作(例如调用后端 API) 只是触发 action 的话,异步操作将会在 action 内部执行:

const actions = {
    addBook({ commit }) {
        request.get(BOOK_API).then(res => commit(ADD_BOOK, res.body.new_book))
    }
}

可以看出,这里的状态变更相当于是 action 产生的副作用,mutation 的 作用是将这些副作用记录下来,这样就形成了一个完整数据流闭环,数据 流的顺序如下:

在视图中触发 action,并根据实际情况传入需要的参数。

在 action 中触发所需的 mutation,在 mutation 函数中改变 state。

通过 getter/setter 实现的双向绑定会自动更新对应的视图。

MobX

MobX 是一个比较新的状态管理库,它的前身是 Mobservable,实际上 MobX 相当于是 Mobservable 的 2.0 版本。

Mobx 和 Redux 相比,差别就比较大了。如果说 Redux 吸收并发扬了很 多函数式编程思想的话,Mobx 则更多体现了面向对象及的特点。MobX 的特点总结起来有以下几点:

Observable。它的 state 是可被观察的,无论是基本数据类型还是引用数 据类型,都可以使用 MobX 的 (@)observable 来转变为 observable value。

Reactions。它包含不同的概念,基于被观察数据的更新导致某个计算值 (computed values),或者是发送网络请求以及更新视图等,都属于响应的范畴,这也是响应式编程(Reactive Programming)在 JavaScript 中的一 个应用。

Actions。它相当于所有响应的源头,例如用户在视图上的操作,或是某个 网络请求的响应导致的被观察数据的变更。 和 Redux 对单向数据流的严格规范不同,Mobx 只专注于从 store 到 view 的过程。在 Redux 中,数据的变更需要监听(可见上文 Redux 示例 代码),而 Mobx 的数据依赖是基于运行时的,这点和 Vuex 更为接近。

总结

状态管理的研究并不是前端领域独有的问题,实际上前端状态管理的很多 思想都是借鉴于成熟很多的软件开发体系。相对于软件开发,前端还是一 个很新的领域,只有多学习其他领域的优秀经验前端界才能发展得更好。

Guess you like

Origin blog.csdn.net/weixin_40851188/article/details/91352417