监听路由事件

这里有一个很常见的需求,我们需要在进入页面的时候,发起请求页面初始化数据。 这里我们通过dva model的subscriptions实现。

./src/models/hero.js subscriptions

  1. subscriptions: {
  2. setup({ dispatch, history }) {
  3. return history.listen(({ pathname, query }) => {
  4. if (pathname === '/hero') {
  5. dispatch({
  6. type: 'fetch'
  7. })
  8. }
  9. });
  10. }
  11. },

这里需要注意的是,subscriptions是一个全局的监听,就是说,当设定触发条件满足时,所有的subscriptions都会响应,所以我们在这里判断了路由为当前路由时,发起一个effects事件。

./src/models/hero.js effects

然后在effects里面,响应这个事件。

  1. effects: {
  2. *fetch({ type, payload }, { put, call, select }) {
  3. const data = [
  4. {
  5. ename: 105,
  6. cname: '廉颇',
  7. title: '正义爆轰',
  8. new_type: 0,
  9. hero_type: 3,
  10. skin_name: '正义爆轰|地狱岩魂',
  11. },
  12. {
  13. ename: 106,
  14. cname: '小乔',
  15. title: '恋之微风',
  16. new_type: 0,
  17. hero_type: 2,
  18. skin_name: '恋之微风|万圣前夜|天鹅之梦|纯白花嫁|缤纷独角兽',
  19. },
  20. ];
  21. yield put({
  22. type: 'save',
  23. payload: {
  24. heros: data,
  25. },
  26. });
  27. },
  28. },

这里的*fetch前面的*表示它是一个异步函数,你可以在里面使用yield进行等待操作。 这里的put方法和dispatch方法可以理解为同一个方法,只是在不同的地方,用不同的方法名表示而已。 这里我们写了一个静态数据,然后又发起了一个叫做save的事件。

./src/models/hero.js reducers

最终我们在reducers中响应了这个save事件,用于更新页面数据,触发页面更新。

  1. reducers: {
  2. save(state, action) {
  3. return { ...state, ...action.payload };
  4. },
  5. },

这里我们定义了一个比较通用的方法,在effects发起需要更新数据时,全部发起save事件。然后在save中只是简单的把payload解构出来,部分覆盖了页面的state。 当然我们这次的effects-fetch里发起了更新一个叫做heros的对象,但是我们的页面state中没有。

  1. state:'hero'

所以我们还要修改我们页面的state

  1. state: {
  2. heros: [],
  3. },

修改完,保存,我们的页面报错了。

WX20181206-222159@2x.png | center | 747x327

./src/pages/hero.js

因为上一节,我们在页面中使用了hero

  1. <h2>This is {props.hero}</h2>

那时候它是一个字符串,但是现在他是一个对象。我们可以简单的将它转化成字符串

  1. <h2>This is {JSON.stringify(props.hero)}</h2>

WX20181206-222436@2x.png | center | 747x312

这样我们就实现了,监听路由事件取得静态数据,修改页面state,触发页面重绘。

代码回顾:这节课的全部代码