您的位置:首页 > Web前端 > React

React框架 dva 和 mobx 的使用感受

2018-02-03 15:54 330 查看
最近在用react写web项目,领导为了让前端便于维护要求都用react作为开发基础,框架选型不限。在使用 react 的时候或多或少会接触到状态管理,从开始学 react 到现在也挺久了,做一些前端框架选型总结。

dva
经朋友推荐开始接触 dva ,从 2.x 版本开始使用,我也基于这个工具开发了一套项目模版,它简化了 redux 的使用,并且在封装了 redux-saga 和 react-router,同时还可以包含 dva-loading 插件获取 loading 状态等。

在 redux 时代,当我需要新增一种跨页面全局数据的时候,我需要去项目的 reducers 目录定义一下这种数据命名和初始值,然后在 constans 目录中为更改这项数据的操作定义一种唯一的操作类型(type),再去 actions 目录定义一些方法,这些方法最后会得到更改后的数据和操作类型(type),最后再回到 reducers 中根据这个操作类型(type)把数据整合到 reducer 中…可以看到,我在编写 redux 这部分代码的时候需要频繁在 actions 、 constants 、 reducers 这几个目录间切换。

而使用 dva 就可以免除这些困扰了,我只需要一个 model 中就可以完成所有操作:

// app全局性状态管理
import * as appApis from '../services/app'; // 异步请求接口

export default {
namespace: 'app',

state: {
channels: [],
show: true
},

reducers: {
getChannelsAndGamesSuccess(state, { channels, games }) {
return { ...state, channels, games };
},
changeShow(state, { show }) {
return { ...state, show };
}
},

effects: { // 异步
* getChannelsAndGames(_, { call, put }) {
const res = yield call(appApis.getChannelsAndGames);
yield put({
type: 'getChannelsAndGamesSuccess',
channels: res.channels
});
}
},

subscriptions: { // 订阅
setup({dispatch, history}) {
history.listen(location => {
if (location.pathname == '/') {
dispatch({
type: 'getChannelsAndGames'
});
}
});
}
}
};


  

这便是一个 model 对象,state 定义数据、effects 中执行异步请求、触发 action 在 reducers 中改变数据,一气呵成!

此外它还含有其他特性,比如:subscription(订阅),可以在这里订阅 history 路由变化,进入根路径执行
getChannelsAndGames
获取数据,而不需要在 react 的生命周期中做这些事;用上 dva-loading 插件,在更改数据的过程中还会自动设置 loading 状态,这在异步请求中非常有用!

dva官网:https://github.com/dvajs/dva/blob/master/README_zh-CN.md

mobx

既然 dva 这么好用,为什么还要使用 mobx 呢?还不是为了折腾😅,用了才能知道两者的优劣,同样的基于 mobx 我也创建了一个项目模版。

在使用 dva 的时候,但凡遇到异步请求的时候都需要先定义一个 effects ,请求完成后再触发一个 action 去修改数据,于是,强迫症作怪,这两者的命名总是让我感觉难受和啰嗦,你可以看到我都是定义为
getXxx
getXxxSuccess


action 是修改 state 的唯一途径,是的,所有的状态管理库都是这样的,但是 mobx 通过一些工具函数解决了这一问题:

// app全局性状态管理
import { observable, action, runInAction } from 'mobx';
import * as appApis from '../services/app';

export default class AppStore {
@observable show = true;
@observable list = [];

@action toggleShow = () => { this.show = !this.show; }
@action getData = async (params) => {
try {
const res = await appApis.getTopicsList(params);
// await 之后,再次修改状态需要动作:
runInAction(() => {
this.list = res.data;
});
} catch (e) {
console.error(e);
}
}
}

/**
* -----------------------------------------------------------------
*/
// app全局性状态管理
import { observable, action } from 'mobx';
import { asyncAction } from "mobx-utils"
import * as appApis from '../services/app';

export default class AppStore {
@observable show = true;
@observable list = [];

@action toggleShow = () => { this.show = !this.show; }
@asyncAction * getData(params) { // <- 注意*号,这是一个 generator 函数!
try {
const res = yield appApis.getTopicsList(params); // 用 yield 代替 await
this.list = res.data;
} catch (e) {
console.error(e);
}
}
}


  

以上是我最喜欢的两种写法,分别借助了
runInAction
asyncAction
这两个工具函数,当然,还有其他方法可以参考。

mobx官网:http://cn.mobx.js.org/

总结

不管是 redux 、 dva ,还是 mobx ,每种技术的出现都是为了带给我们更好的开发体验、更高的开发效率,也伴随着不一样的学习成本,虽然 mobx 可以治好我的强迫症,但是也反逼我去学习了修饰器;虽然看起来 redux 是最繁琐的,但是它可能是对新手最友好的,参考资料也是最多的,也能够一步步让我知道状态是如何改变的,再者,如果我没使用过 redux ,未必能体会到后两者带给我怎样的便利之处。

还有这个UI组件工具也必不可少:
https://ant.design/docs/react/introduce-cn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: