使用 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'; ---step1
interface PageProps extends ConnectProps {
hero: HeroModelState;
}
const Hero: FC<PageProps> = (props) => { ---step2
console.log(props.hero); ---step4
return (
<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