MobX - 基于响应式的状态管理
前言
MobX 是 Redux 之后的一個狀態管理庫,它相較于 redux 更輕量,整體是一個觀察者模式的架構,存儲 state 的 store 是被觀察者,使用 store 的組件是觀察者。MobX 可以有多個 store 對象,并且 store 使用的 state 是可以改變的。
概念簡介
MobX 通過函數響應式編程的思想使得狀態管理變得簡單和易于擴展,其背后的哲學是:任何從應用程序的狀態中獲取/衍生的數據都應該可以自動被獲取/衍生。和 Redux 一樣,MobX 也是采用單向數據流:通過 action 改變應用的 state ,state 的改變會導致 view 的更新。
MobX 包含 4 個概念:state(狀態)、computed value(計算值),reaction(響應),action(動作)。state 的更新過程是同步執行的,也就是說,action 更改 state 后,新的 state 可以立即被獲取。而 computed value 采用的是延遲更新,只有當它被使用的時候才會重新計算值,當使用 computed value 的組件被卸載時,它也會被自動回收。
MobX 中提到的 state 指的是可以觀測的 state,因為對于不可觀測的 state ,他們的修改并不會自動產生影響,對 MobX 的數據流來說是沒有意義的。
MobX 中大量使用了 ES.next 的裝飾器語法,這也是官方所推薦的,但裝飾器語法目前還處于實驗階段,需要安裝 babel-plugin-transform-decorators-legacy 這個 babel 插件。
簡單的 Todos 應用
通過 Todos 應用來簡單介紹這 4 個概念。使用 class 定義一個可觀測的 state Todo,代表一項任務:
import { observable } from "mobx"; class Todo {id = Math.random();@observable title = "";@observable finished = false; } 復制代碼這里使用的 @observable 就是裝飾器語法,也可以使用 ES5 語法實現等價代碼:
import { extendObservable } from "mobx"; function Todo {this.id = Math.random();extendObservable(this, {title: "",finished: false}); } 復制代碼經過 @observable 的修飾之后,Todo 的 title 和 finished 兩個屬性就變成可觀測狀態,他們的改變會自動被觀察者獲知。id 沒有被 @observable 修飾,所以它只是一個普通屬性。 基于可觀測的 state 可以創建 computed value。例如,todos 中需要獲取未完成任務的總數,使用 @computed 定義一個 unfinishedTodoCount,計算未完成任務的總數:
import { observable, computed } from "mobx"; class TodoList {@observable todos = [];@computed get unfinishedTodoCount() {return this.todos.filter(todo => !todo.finished).length;} } 復制代碼TodoList的屬性 todos 也是一個可觀測的屬性,數組里存放的是前面定義的 Todo 實例對象。當 todos 中的元素數量發生變化或者其中某個 todo 元素的 finished 屬性變化,unfinishedTodoCount 都會自動更新(在使用的時候)。 除了 computed value 會響應 state 的變化,reaction 也會響應 state 的變化,不同的是,reaction 并不是創建一個新值,它是用來執行有副作用的邏輯,比如輸出日志、發送請求等。mobx-react 提供了 @observer 裝飾器和 observer 函數,可以將 React 組件封裝成 reaction,自動根據 state 的變化更新 UI 組件。例如,創建 TodoListView 和 TodoView 兩個組件代表應用的 UI:
import React, { Component } from "react"; import ReactDOM from "react-dom"; import { oberver } from "mobx-react"; import { action } from "mobx";@observer class TodoListView extends Component {render() {return (<div><ul>{this.props.todoList.map(todo => {<TodoView todo={todo} key={todo.id} />;})}</ul>Tasks left: {this.props.todoList.unfinishedTodoCount}</div>);} }const TodoView = oberver(({ todo }) => {const handleClick = action(() => todo.finished = !todo.finished)return (<li><input type="checkbox" checked={todo.finished} onClick={handleClick}/>{todo.title}</li>); });const store = new TodoList(); ReactDOM.render(<TodoListView todoList={store} />, document.getElementById("root") ); 復制代碼TodoListView 使用到了可觀測的數據:todos 和 todo.finished(通過 unfinishedTodoCount 間接使用的),所以它們的改變會觸發 TodoListView 的視圖更新。 TodoView 中的 handleClick 是用來改變 todo.finished 的 action,也就是通過 mobX 更改應用的狀態,一般習慣使用 mobX 提供的 action 包裝應用中定義的 action,
參考
MobX
React 進階之路
轉載于:https://juejin.im/post/5c16609d6fb9a04a0604c477
總結
以上是生活随笔為你收集整理的MobX - 基于响应式的状态管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS实现省市联动效果
- 下一篇: 数组去重一步到位