这里有一个很常见的需求,我们需要在进入页面的时候,发起请求页面初始化数据。这里我们通过 dva model 的 subscriptions 实现。
src/models/hero.ts subscriptions
import { Effect, Reducer, Subscription } from 'umi';export interface HeroModelType {namespace: 'hero';state: HeroModelState;effects: {query: Effect;};reducers: {save: Reducer<HeroModelState>;};+ subscriptions: { setup: Subscription };}HeroModel 中增加 subscriptionssubscriptions: {setup({ dispatch, history }) {return history.listen(({ pathname, query }) => {if (pathname === '/hero') {dispatch({type: 'fetch'})}});}},
这里需要注意的是,subscriptions 是一个全局的监听,就是说,当设定触发条件满足时,所有的 subscriptions 都会响应,所以我们在这里判断了路由为当前路由时,发起一个 effects 事件。
src/models/hero.ts effects
然后在 effects 里面,响应这个事件。
effects: {*fetch({ type, payload }, { put, call, select }) {const data = [{ename: 105,cname: '廉颇',title: '正义爆轰',new_type: 0,hero_type: 3,skin_name: '正义爆轰|地狱岩魂',},{ename: 106,cname: '小乔',title: '恋之微风',new_type: 0,hero_type: 2,skin_name: '恋之微风|万圣前夜|天鹅之梦|纯白花嫁|缤纷独角兽',},];yield put({type: 'save',payload: {heros: data,},});},},
这里的 *fetch 前面的 * 表示它是一个异步函数,你可以在里面使用 yield 进行等待操作(什么是 Effect ?)。这里的 put 方法和 dispatch 方法可以理解为同一个方法,只是在不同的地方,用不同的方法名表示而已。这里我们写了一个静态数据,然后又发起了一个叫做 save 的事件。
别忘了在类型定义里面增加属性定义哦
export interface HeroModelType {namespace: 'hero';state: HeroModelState;effects: {query: Effect;fetch: Effect;};reducers: {save: Reducer<HeroModelState>;};subscriptions: { setup: Subscription };}
src/models/hero.js reducers
最终我们在 reducers 中响应了这个 save 事件,用于更新页面数据,触发页面更新。
reducers: {save(state, action) {return { ...state, ...action.payload };},},
这里我们定义了一个比较通用的方法,在 effects 发起需要更新数据时,全部发起 save 事件。然后在 save 中只是简单的把 payload 解构出来,部分覆盖了页面的 state 。当然我们这次的 effect/fetch 里发起了更新一个叫做 heros 的对象,但是我们的页面 state 中没有。
state:{name:''}
所以我们还要修改我们页面的state
state: {name:'',heros: [],},
修改完,保存,修改页面,因为 heros 是一个对象。我们可以简单的将它转化成字符串
<h2>This is {JSON.stringify(props.hero)}</h2>

这样我们就实现了,监听路由事件取得静态数据,修改页面 state ,触发页面重绘。
别忘了state的类型定义
export interface HeroModelState {name: string;heros: [];}
