redux-saga(redux-saga-in-chinese.js.org/)
redux-saga 是⼀个⽤于管理应⽤程序 Side Effect(副作⽤,例如异步获取数据,访问浏 览器缓存等)的 library,它的⽬标是让副作⽤管理更容易,执⾏更⾼效,测试更简单,在处理故 障时更容易(减少异步回调).
effects
effect 是⼀个 javascript 对象,⾥⾯包含描述副作⽤的信息,可以通过 yield 传达给 sagaMiddleware执⾏。在 redux-saga 世界⾥,所有的 effect 都必须被 yield 才会执⾏,所以有⼈写了 eslint-plugin-redux- saga 来检查是否每个 Effect 都被 yield。并且原则上来说,所有的 yield 后⾯也只能跟effect,以保证代 码的易测性。
put
作⽤和 redux 中的 dispatch 相同。
yield put({ type: LOGIN_SUCCESS);
call与fork:阻塞调⽤和⽆阻塞调⽤
redux-saga 可以⽤ fork 和 call 来调⽤⼦ saga ,其中 fork 是⽆阻塞型调⽤,call 是阻塞型调⽤,即call 是有阻塞地调⽤ saga 或者返回 promise 的函数。
take
等待 redux dispatch 匹配某个 pattern 的 action 。
function* loginSaga(props) { // yield takeEvery("login", loginHandle); // 等同于 const action = yield take(LOGIN_SAGA); yield fork(loginHandle, action); }
takeEvery
takeEvery(pattern, saga, ...args) takeEvery 可以让多个 saga 任务并⾏被 fork 执⾏。 在发起(dispatch)到 Store 并且匹配 pattern 的每⼀个 action 上派⽣⼀个 saga 。
import {fork, take} from "redux-saga/effects" const takeEvery = (pattern, saga, ...args) => fork(function*() { while (true) { const action = yield take(pattern) yield fork(saga, ...args.concat(action)) } })
redux-saga 使⽤了 ES6 的 Generator 功能,让异步的流程更易于读取,写⼊和测试。 (如果你还不熟 悉的话,这⾥有⼀些介绍性的链接 ) 通过这样的⽅式,这些异步的流程看起来就像是标准同步的 Javascript 代码。(有点像 async / await ,但 Generator 还有⼀些更棒⽽且我们也需要的功能)。 不同于 redux-thunk,你不会再遇到回调地狱了,你可以很容易地测试异步流程并保持你的 action 是⼲ 净的,因此我们可以说redux-saga更擅⻓解决复杂异步这样的场景,也更便于测试。
index.js
store/index.js
store/loginReducer.js
action/loginSaga.js
action/rootSaga.js
service/login.js
routes/privateRoute.js
dva(dvajs.com/)
dav首先是一个基于redux和redux-saga的数据流方案,然后为了简化开发体验,dva还额外内置了react-router和fetch,所以也可以理解为一个轻量级的应用框架。
dva特性:
易学易用:仅有6个api,对redux用户友好,配合umi使用后更是降低为0api.
elm概念:通过reducers,effects和subscriptions组织model
插件机制:比如dva-loading可以自动处理loading状态,不用一遍遍地写showLoading和hideLoading
支持HRM(模块热替代):基于babel-plugin-dva-hmr实现components,routes和models的HMR
dva数据流向
数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变 数据的时候可以通过 dispatch 发起一个 action,如果是同步行为会直接通过 Reducers 改变 State ,如果是异步行为(副作用)会先触发 Effects 然后流向 Reducers 最终改变 State ,所以在 dva 中,数据流向非常清晰简明,并且思路基本跟开源社区保持一致(也是来自于开源社区)
理解dva
软件分层:回顾react,为了让数据流更易于维护,我们分成了store,reducer,action等模块,各司其 职,软件开发也是一样。
- Page 负责与用户直接打交道:渲染页面、接受用户的操作输入,侧重于 展示型交互性逻辑 。
- Model 负责处理业务逻辑,为 Page 做数据、状态的读写、变换、暂存等。
- Service 负责与 HTTP 接口对接,进行纯粹的数据读写。
DVA 是基于 redux、redux-saga 和 react-router 的轻量级前端框架及最佳实践沉淀,核心api如下:
1.model(stats状态,action,dispatch,reducer,effect副作用,异步处理)
2.subscriptiond订阅
3.router路由
(1) namespace :model 的命名空间,只能用字符串。一个大型应用可能包含多个 model,通
过 namespace 区分
(2) reducers :用于修改 state ,由 action 触发。reducer 是一个纯函数,它接受当前的
state 及一个 action 对象。action 对象里面可以包含数据体(payload)作为入参,需要返
回一个新的 state。
(3) effects :用于处理异步操作(例如:与服务端交互)和业务逻辑,也是由 action 触发。
但是,它不可以修改 state,要通过触发 action 调用 reducer 实现对 state 的间接操作。
(4)action :是 reducers 及 effects 的触发器,一般是一个对象,形如 { type: 'add',
payload: todo } ,通过 type 属性可以匹配到具体某个 reducer 或者 effect,payload 属
性则是数据体,用于传送给 reducer 或 effect。
umi(umijs.org/zh-CN/docs)
umi是一个可插拔的企业级 react 应用框架。
umi具备一下功能:
create-react-app
create-react-app 是基于 webpack 的打包层方案,包含 build、dev、lint 等,他在打包层把体验做到
了极致,但是不包含路由,不是框架,也不支持配置。所以,如果大家想基于他修改部分配置,或者希
望在打包层之外也做技术收敛时,就会遇到困难。
next.js
next.js 是个很好的选择,Umi 很多功能是参考 next.js 做的。要说有哪些地方不如 Umi,我觉得可能是
不够贴近业务,不够接地气。比如 antd、dva 的深度整合,比如国际化、权限、数据流、配置式路
由、补丁方案、自动化 external 方面等等一线开发者才会遇到的问题。
** umi目录结构**
react Antd Pro(pro.ant.design/zh-CN/docs/…
Ant Design Pro 在力求提供开箱即用的开发体验,为此我们提供完整的脚手架,涉及国际化,mock,数据流,网络请求等各个方面。为这些中后台中常见的方案提供了最佳实践来减少学习和开发成本