umi 中内置了 Dva 插件,不用下载可以直接使用。
一、创建配置文件
在项目的 src 目录中创建 models 目录作为 dva 的配置文件目录(创建完成后重启一下项目)。
然后在 models 中创建 playList.js 文件。
二、配置 Dva
import { getPlayListAsync } from '../api/playList'
export default {
state: {
// 歌单数据
data: []
},
reducers: {
setPlayList(state, action) {
state.data = action.payload;
}
},
effects: {
*getPlayListSaga({ payload }, { put, call }) {
// 调用 api 发送请求
const res = yield call(getPlayListAsync);
if (res.code === 200) {
// 调用 reducers,将数据更新到 state 中
yield put({ type: 'setPlayList', payload: res.result })
}
}
}
}
文件名会自动作为 namespace 的属性值。
三、组件中触发 saga 方法
组件中通过 useDispatch() 获取到 dispatch 方法。
import React, { useEffect, useState } from 'react';
import { getPlayListAsync } from '../../api/playList';
import { useDispatch, useSelector } from 'umi'
export default function Discover() {
useEffect(() => {
// 发送请求获取数据
getPlayList();
}, [])
// 获取 dispatch 方法
const dispatch = useDispatch();
// 获取状态机中的数据
const playList = useSelector((state) => {
return state.playList.data
})
const getPlayList = async () => {
dispatch({ type: 'playList/getPlayListSaga' })
}
return (
// ...
);
}
四、immer 属性
基于 React 的特点,Dva 中通过 reducers 修改数据时,我们必须返回一个新的 state 对象。
而 umi 中提供了一个 immer 属性,我们在 umirc.ts 中,添加以下配置:
{
dva: {
immer: true
}
}
配置完成后,我们再在 reducer 中修改 state 数据时,就可以直接对 state 进行赋值,不用考虑地址问题了。