umi3 使用 dva 的流程及理解(model数据使用教程)-reducer,effects-subscriptions,connect,parame/query
下面是model的基本结构
TypeScript
{
namespace: String,
// 命名空间名字,必填
//namespace: 'global' 说明以下此处的dva命名空间为 global,即你调用的时候需要采用 global.XXX 的形式
state: Object,
// 状态 reducer: Object,
// 同步更新 state 修改状态 effects: Object,
// 副作用:处理异步逻辑
//当数据需要从服务器获取时,需要发起异步请求,请求到数据之后,通过调用 Reducers更新数据到全局state
subscriptions: Object
// 订阅数据源
}
1.reducer
用来处理同步操作。如果不需要调接口时候,我们前台传递的 action(不懂的小伙伴不着急,下面有微讲解) 可以直接调用 reducers里的方法。
reducer是一个函数,接收state 和 action,返回老的或新的state。 即: save(state, action) {undefined return { …state, …action.payload }; },
state:为当前 Model 下的所有 state 值,可以 console.log(state) 看一下输出就知道了。
action:当前台页面需要进行数据操作时,就会创建一个 action,action 存放了传递过来需要对当前 state 进行改变的数据。
TypeScript
reducers: {
changeTitle(state, {
payload: {
num
}
) {
//changeTitle可以理解为一个方法名
//payload:就是 action 里传递过来的数据。
//num 是传过来的,名字随便起,不是state中的num,这接收一个action
return {
...state,
...num
}
//return:返回的是新的 state。等于舍弃了旧的 state,重新 return 一个新的 state 作为当前 Model 的 state。
//一般情况下,我们要解开旧的 state,将它重新赋值给新的 state。...state 为 ES6 语法。
//将操作完成得数据累加到 return 中。
//同名的数据会覆盖,所以不用担心旧的 state 值会影响到新设置的值。
//不同名的数据会追加。
},
TypeScript
//页面调用
//页面使用dispatch进行使用
this.props.dispatch({
type: 'pageModel/changeTitle',
//namespace+需要调用的reducer方法
payload: 'Hello World',
});
2.effects
用来处理异步操作。如果需要调取接口的话,前台页面就需要调用 effects 里的方法。 将数据取出来,在传递给 reducers 里的方法进行数据操作和同步 state。
Dva 中的异步操作都放到 effects 中管理,基于 Redux-saga 实现 Effect 是一个 Generator函数,内部使用 yield 关键字,标识每一步的操作
每一个 effect 都可以接收两个参数:
1、包含 dispatch 携带参数 payload 的 action 对象
2、dva 提供的 effect 函数内部的处理函数集
第二个参数提供的处理函数中,常用的有 call、put、select call: 执行异步函数 put: 发出一个 Action,类似于
dispatch 触发reducer改变state select: 返回 model 中的 state //用于从state里获取数据
1.call
TypeScript
service中异步请求(cardsService.js) request 是我们封装的一个网络请求库
TypeScript
async function deleteOne(data) { return request("queryFromApi", { data, method: "post", dataType: "payload" }) }
2.select
TypeScript
*deleteOne({ payload }, { select, put }) { effects:{ const m = yield select((state) => state.test.num) //select就是用来选择上面state里的数据 }
3.put
TypeScript
yield put({ type: "addNum", // put:用来发出事件,即 action。一般调用 reducers 下的方法进行同步数据。 //type:该 Model 层里 reducers 下的方法名。 //payload:参数的传递。 payload: { num: data, // 把后台返回的数据赋值给了num //假如那个reducer中方法是由这里effects去触发的,那个num名必须是这里名字num,如果reducer中方法不是这触发,那名字可随便起 return rsp; }, } }
3.subscriptions
TypeScript
// 订阅监听,比如我们监听路由,进入页面就如何,可以在这写 setup ({ dispatch, history, query }) { return history.listen( async ({ pathname, search, query}) => { if (pathname==="/testdemo") {// 当进入testdemo这路由,就会触发fetchUser方法 dispatch({ type: "fetchUser" }) } }) }
4.connect
connect 连接 Model 和 Route 页面下的数据
dva 有提供 connect 方法。只要在每个 Routes 页面导入下面的代码即可。
TypeScript
import { connect } from 'dva';
对于组件:
我们在最后导出时使用 connect 进行与 Models 的连接。
TypeScript
export default connect(({index}) => ({index}))(IndexPage);
//解释一下 index:index 为 Model 层里面的 namespace。
前台调用 Model 层方法
TypeScript
const { dispatch } = this.props; //在 dva 中,可以通过 `this.props` 直接取得 `dispatch`
TypeScript
dispatch ({ type:'example/fetch', //指定哪个 model 层里面的哪个 方法 payload:{name:'exampleNew'}, //需要传递到 model 层里面的参数。 //payload 为固定用法(我自己的理解)。 })
5.parame和query传值
query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示
版权声明:本文为CSDN博主「跳跳的小古风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43787651/article/details/112304132