开启 dva,config/config.ts
dva: { immer: true, }
- 如需兼容 IE11,需配置 { immer: { enableES5: true }}
model
model规范:符合以下规则的文件会被认为是 model 文件
src/models 下的文件
src/pages 下,子目录中 models 目录下的文件
src/pages 下,所有 model.ts 文件
models/home.js
export default {
namespace: 'home',
state: {
dataSource: [],
title: '',
},
reducers: {
save(state, action) {
return {...state, ...action.payload};
},
},
effects: {
*login({ payload }, { call, put }) {
try {
const { code, userinfo } = yield call(loginReq, payload);
localStorage.setItem('userinfo', JSON.stringify(userinfo));
// 触发reducers更新状态
// 犹如import { call, put, takeEvery } from 'redux-saga/effects'中的takeEvery
yield put({
type: 'init',
payload: userinfo,
});
history.push('/');
} catch (error) {
console.log(error);
}
},
}
}
model注册
自己写的model,umi会自动将其按照,命名空间的名称加入到全局变量里面
- 开启dva的热跟新,在组件中引用,就直接可以从umi中引出自己定义的model
- umi会将 models下的文件,已命名空间的方式,加入到 dva 的 connect里面
组件
useStore
在组件导入中将useSelector, useDispatch 导入
import React, { useState, useEffect } from 'react'
import { connect, useDispatch, useStore, useSelector } from 'umi';
function App() {
const dispatch = useDispatch();
// 与redux使用方法相似,store为所有的model模块,详细见下图
const state = useSelector(store => store.home);
function onClick() {
// home 是model的唯一namespace,save是其reducers中方法
dispatch({
type: 'home/save',
payLoad: { name: 'lucy' }
});
}
return (
<div>
<button onClick={onClick}>改变state中的值</button>
</div>
);
}
export default App;
connect
import React, { useState, useEffect } from 'react';
import {object} from 'prop-types';
import { connect } from 'umi';
import { TabList } from '@/components';
Dashboard.propTypes = {
state: object.isRequired,
};
function Dashboard({state, _$init}) {
const [tabKey, setTabKey] = useState('');
useEffect(() => { _$init() }, []);
function tabChange(key) {
setTabKey(key);
}
const TabListProps = {
type: 'card',
value: tabKey,
dataSource: tabSource,
onChange: tabChange,
}
return (
<div>
<TabList {...TabListProps} />
</div>
);
}
function mapStateToProps(state) {
// console.log('state', state)
return {
state: state.dashboard
}
}
function mapDispatchToProps(dispatch) {
return {
_$init: payload => dispatch({payload, type: 'dashboard/init'})
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard);