使用 dva
在 umi@3 中要使用 dva 的功能很简单,只要使用安装 @umijs/plugin-dva 并在 配置文件中开启 dva 配置。
yarn add @umijs/plugin-dva
如果提示 dva 不是约定的配置,说明你没有装 @umijs/plugin-dva ,如果你 dva 没有生效,可能是你配置没开启
教程在前面使用 create-umi-app 初始化项目时,依赖了 @umijs/preset-react ,这是一个插件集,你无需再而外安装 plugin-dva ,只需要再配置中开启即可。打开 umi 的配置文件:
./umirc.js
import { defineConfig } from 'umi';export default defineConfig({dva: {},antd: {}});
新增 model 文件
umi 中启用 dva 时,约定 ./src/models/ 目录下的  model 文件将被视为 model 模块 ,可以在页面中使用。
这里的 model 模块不仅仅是指 dva model 还有可能是 useModel 的模块。umi会自己判断,这里我们先新建dva的模块就好。
新建 ./src/models/hero.ts
import { Effect, Reducer } from 'umi';export interface HeroModelState {name: string;}export interface HeroModelType {namespace: 'hero';state: HeroModelState;effects: {query: Effect;};reducers: {save: Reducer<HeroModelState>;};}const HeroModel: HeroModelType = {namespace: 'hero',state: {name: 'hero',},effects: {*query({ payload }, { call, put }) {},},reducers: {save(state, action) {return {...state,...action.payload,};},},};export default HeroModel;
关于这个文件的详细说明,可以查看导读的《五分钟掌握最小知识体系》。这里需要说明的是,如果文件中的 namespace 未写明,umi 会使用文件名作为 model 的 namespace。为了减少错误的出现,最好保持所有的 model 文件,文件名不同。
在页面中使用model
在这里我们需要引入 dva 的 connect 将页面和 model 绑定在一起,我们稍微改造一下页面的结构:
./src/pages/hero.tsx
import React, { FC } from 'react';import styles from './hero.css';import { connect, HeroModelState, ConnectProps } from 'umi'; ---step1interface PageProps extends ConnectProps {hero: HeroModelState;}const Hero: FC<PageProps> = (props) => { ---step2console.log(props.hero); ---step4return (<div><h1 className={styles.title}>Page hero</h1><h2>This is {props.hero.name}</h2></div>);}export default connect(({ hero }: { hero: HeroModelState }) => ({ hero }))(Hero);--- step3
- step1 在文件头部引入了 umi 的connect,HeroModelState, ConnectProps
 - step2 把之前的匿名函数,改成实名函数Hero
 - step3 使用connect连接页面和models
 - step4 从属性中取出namespace为hero的model的state数据。
 
这里有一点点绕口,比如我们现在定义的是
如果定义的是一个对象
> state: 'hero',> console.log(props.hero);hero
state: {text: 'page work',list: []},console.log(props.hero);{text: 'page work',list: []}
编辑完保存,启动 umi 开发服务器:

使用同样的方法新建 ./src/models/item.js和 ./src/models/summoner.js ,并同步修改 ./src/pages/item.js 和 ./src/pages/summoner.js 。
最终效果

目录结构
.├── layouts│ ├── index.less│ └── index.tsx├── models│ ├── hero.ts│ ├── item.ts│ └── summoner.ts└── pages├── hero.less├── hero.tsx├── index.less├── index.tsx├── item.less├── item.tsx├── summoner.less└── summoner.tsx
