react中使用mobx6以及持久化存储mobx-persist-store
mobx6官方文档
mobx-persist-store文档
安装mobx及mobx-persist-store
yarn add mobx mobx-react mobx-persist-store --save
在项目中使用mobx
- 在src目录下新建store文件夹,新建index.js文件
模块化开发,统一的数据仓库有利于数据管理与分发,也可以向mobx5一样在不同的模块下建state
- 定义类,一般以模块划分,如以下示例
import { makeAutoObservable } from "mobx" class AppState { userInfo = null; // 定义数据 constructor() { // 构造函数 makeAutoObservable(this) // 自动监测数据 --这里和mobx6之前的版本不同,不再使用装饰器语法 } // 修改数据函数 setUserInfo = (userInfo = null) => { this.userInfo = userInfo } // computed -- 依赖的数据自动计算返回一个数据 - 类似于vue中的computed get token(){ return this.userInfo ? this.userInfo.token : '' } } export default new AppState() // 导出
- 在页面中使用
import AppState from "../../store/app" const Todo = (props) =>{ return( <> <div>{AppState.token}</div> </> ) } export default Todo;
- 在页面中监听数据变化,实时响应
如果页面需要实时对mobx数据变化做出响应,那么需要添加observer来监测数据变化。
import AppState from "../../store/app" import { observer } from "mobx-react"; const Todo = observer((props) =>{ return( <> <div>{AppState.token}</div> </> ) }) export default Todo;
mobx6数据持久化存储mobx-persist-store
无论是使用vuex或者mobx,我们都会遇到这么一个问题,那就是在页面刷新的时候数据会丢失的情况。可以使用mobx-persist-store来解决这个问题。
- 在store/index.js中加入以下代码,直接上例子
import { action,toJS } from "mobx"
import { makeAutoObservable } from "mobx"
import { makePersistable,isHydrated } from "mobx-persist-store"; // 引入相关api
class AppState {
userInfo = null;
constructor() {
makeAutoObservable(this, {}, { autoBind: true })
makePersistable(this, { // 在构造函数内使用 makePersistable
name:'UserStore', // 保存的name,用于在storage中的名称标识,只要不和storage中其他名称重复就可以
properties: ["userInfo"], // 要保存的字段,这些字段会被保存在name对应的storage中,注意:不写在这里面的字段将不会被保存,刷新页面也将丢失:get字段例外。get数据会在数据返回后再自动计算
storage: window.localStorage, // 保存的位置:看自己的业务情况选择,可以是localStorage,sessionstorage
// 。。还有一些其他配置参数,例如数据过期时间等等,可以康康文档,像storage这种字段可以配置在全局配置里,详见文档
}).then(
action((persistStore) => { // persist 完成的回调,在这里可以执行一些拿到数据后需要执行的操作,如果在页面上要判断是否完成persist,使用 isHydrated
console.log(persistStore);
}))
}
setUserInfo = (userInfo = null) => {
this.userInfo = userInfo
}
// 注意这个字段的使用:在页面useEffect的时候,如果你没有添加依赖数组(初始化执行),那么你可能拿不到computed计算的数据(原因是这时候还没有persist结束),所以
// 这个属性还是比较重要的,因为它可以在页面上做判断,当页面load完成,get数据计算完成之后,isHydrated会置为true
get isHydrated() {
return isHydrated(this);
}
get token(){
return this.userInfo ? this.userInfo.token : ''
}
}
export default new AppState()
- 页面上使用
如果你页面初始化有用到mobx里面的值的话,那么需要等待store persist结束,所以在useeffect的时候需要做个判断
js useEffect(()=>{ if(AppState.isHydrated){ // ... 这个时候就可以拿到AppState里缓存的值啦 } return ()=>{ // ... } // eslint-disable-next-line },[AppState.isHydrated])
其他
mobx使用的是proxy对象,所以如果你想要查看你的数据的话,可以使用mobx提供的toJS方法查看。
console.log(toJS(AppState.userInfo))