对于大型前端项目来说,状态管理是一个非常重要的问题。处理数据,并不困难,困难的是如何把项目中这么多的数据处理的漂亮、简单、好理解。当不同页面拿到同一个数据时,要确保两边的数据是相同的,而不会因为请求的延迟导致两边的数据是不相同的。因此,使用一个统一的状态管理工具是非常有必要的。目前 React 的主流状态管理方案是:Redux 和 Mobx。而 Mobx-State-Tree 则是 Mobx 的开发者开发的又一状态管理工具,Mobx State Tree在保留Mobx基本设计理念的同时结合了Redux只有一个store和不可变数据的优点。
安装
//在 react 项目中使用
npx create-react-app mst-demo-1
// 安装
yarn add mobx mobx-react-lite mobx-state-tree
基础概念
核心思想
Root 树。该树由可变的但受严格保护的对象组成,这些对象富含运行时类型信息。换句话说; 每棵树都有一个形状(类型信息)和状态(数据)。从这棵活树中,会自动生成不可变的结构上共享的快照。
可以看到,整个项目的状态相当于是一颗树,Root 作为这颗树的树干,在 Root 树上又挂载着其他不同的树枝(其他的状态数据)。也就是说,不同的树枝处理不同的数据,最后将这些数据统一挂载到 Root 树上,因此,可以通过这个 Root 来访问、更新、修改挂载在上面的所有的数据。
基础概念:
树 = type + state
// type
const Todo = types.model({
title: types.string
})
//state
const coffeeTodo = Todo.create({
title: "Get coffee"
})
起手式
定义模型
import {types} from "mobx-state-tree"
//定义 List 这个”树枝“的结构,是一个包含 title 属性的对象
const List = types.model({ title: types.string })
创建 Root 树,并初始化数据
// 首先需要定义 Root 树的模型
const RootModel = types.model({
lists: List
})
// 初始化数据
const rootStore = RootModel.create({
lists: {
title: 'hello world'
}
})
修改状态
const Todo = types.model({
title: types.string
})
.actions(self => {
return {
setNewTitle(newTitle){
self.title = newTitle
}
}
})
//使用
rootStore.lists.setNewTitle('hello ccc')
向一个对象中添加数据
const RootModel = types
.model({
userList: types.map(List)
}).actions(self => {
return {
addUser(id: string, title:string, done: boolean){
self.userList.set(id, List.create({title, done}))
}
}
});
let initialState = RootModel.create({
userList: {}
});
//调用
rootStore.addUser('1', 'ccc', false)
rootStore.userList.get('1').toggle()
向一个数组中添加数据
const RootModel = types
.model({
listArray: types.array(List)
})
.actions(self => {
return {
addArray(title: string, done: boolean){
self.listArray.push({title, done})
}
}
});
//调用
rootStore.addArray('dog', false)
异步操作
const RootModel = types
.model({
data: types.string
})
.actions(self => (
{
getData: flow(function* getData(){
const data = yield axios('http://xxxx')
self.data = JSON.strinfy(data)
})
}
));
//调用
rootStore.getData()
在 UI 中对 store 进行监听
import {observer} from 'mobx-react-lite';
const User = observer(() => {
const store = useRootStore()
return(
<div>
<p>{JSON.stringify(store)}</p>
</div>
)
})
export default User
通过快照进行更新
//当 rootStroe 改变时,快照就会改变,使用 onSnapshot 来进行监听和记录
onSnapshot(rootStore, snapshot => {
console.log('Snapshot: ', snapshot);
});
类型概述
基础类型
types.string- 字符串类型types.number- 数字类型types.integer- 整数类型types.boolean- 布尔类型types.Date- 日期类型types.custom- 创建一个自定义基本类型
复杂类型
types.model()- 用来描述对象的形状types.array(type)- 声明指定类型的数组。types.map(type)- 声明指定类型的映射。types.model()- 创建一个可链接的模型类型,其中每个链接的方法都会产生一个新的类型.named(name)- 克隆当前类型,但给它一个新名称.props(props)- 根据当前类型生成一个新类型,并添加、覆盖指定的属性.actions(self => ...)- 对当前的数据提供一系列操作.views(self => ..)- 计算属性