序言
umi
为什么使用Umi.js?
generator
生成器函数
yield 同步方式写异步代码
redux-saga
redux-saga是一个用于管理redux应用异步操作的中间件,redux-saga通过创建sagas将所有异步操作逻辑收集在一个地方集中处理,可以用来代替redux-thunk中间件。
Redux-saga是Redux的一个中间件,主要集中处理react架构中的异步处理工作,被定义为generator(ES6)的形式,采用监听的形式进行工作。
dva
为什么要使用dva?
不得不说,当你写过原生 React
后,会发现 Dva
写起来真的是爽歪歪,他对 redux + react-router + redux-saga
进行了一层封装,减少了很多代码操作。同时加上 Umi 强大的路由处理功能,使得开发过程中又一次减少了不少踩坑操作。
正如 Dva 官网所言, Dva 是基于React + Redux + Saga的最佳实践沉淀, 做了 3 件很重要的事情, 大大提升了编码体验。
其实使用React Hooks的目的就是为了去redux,那我为什么还会使用基于redux-soga封装的dva呢?原因就在于hooks虽然很方便,但如果是一些很复杂的状态需要去管理,这时候使用hooks就会有点儿费劲了。所以这时候结合dva来解决这种特别复杂的状态管理是很方便的,原生的redux使用起来稍微有点儿麻烦,dva用起来很简单,很爽,这就是我选择dva的原因。
Dva数据流向
总的来说如下:View层操作 –> 触发models层effect中方法 –> 触发service层请求,获取后台数据 –> 触发model层处理相应数据的方法,存储至reducer中 –> 更新model层中state –> 触发view层的render方法进行重新渲染 –> 页面更新
如何使用dav?
正如 Dva 官网所言, Dva 是基于 React + Redux + Saga 的最佳实践沉淀, 做了 3 件很重要的事情, 大大提升了编码体验:
- 把 store 及 saga 统一为一个 model 的概念, 写在一个 js 文件里面
- 增加了一个 Subscriptions, 用于收集其他来源的 action, eg: 键盘操作
- model 写法很简约, 类似于 DSL 或者 RoR, coding 快得飞起✈️
app.model({ namespace: 'count', state: { record: 0, current: 0, }, reducers: { add(state) { const newCurrent = state.current + 1; return { ...state, record: newCurrent > state.record ? newCurrent : state.record, current: newCurrent, }; }, minus(state) { return { ...state, current: state.current - 1}; }, }, effects: { *add(action, { call, put }) { yield call(delay, 1000); yield put({ type: 'minus' }); }, }, subscriptions: { keyboardWatcher({ dispatch }) { key('⌘+up, ctrl+up', () => { dispatch({type:'add'}) }); }, }, });
聊聊dva 中的 effects 与 reducers以及其中涉及的关键字的使用
使用dva+umi+antd构建页面
编写 UI Component
随着应用的发展,你会需要在多个页面分享 UI 元素 (或在一个页面使用多次),在 umi 里你可以把这部分抽成 component 。
我们来编写一个 ProductList component,这样就能在不同的地方显示产品列表了。
新建 src/components/ProductList.js 文件:
定义 dva Model
完成 UI 后,现在开始处理数据和逻辑。
dva 通过 model 的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的 subscriptions 。
新建 model src/models/products.js,
connect 起来
到这里,我们已经单独完成了 model 和 component,那么他们如何串联起来呢?
dva 提供了 connect 方法。如果你熟悉 redux,这个 connect 来自 react-redux。
subscription:监听派发,用于初始化数据源。
effects:异步派发,用于通过call接口把数据传回来然后转发。
reducer:处理返回,用于把传过来的各类数据各种处理,然后返回。它是state的最后一步。
umi3+dva+typescript重新做一个用户列表的增删改查
但是() => Promise<any>到底是个什么类型呢?