开启 dva,config/config.ts

  1. dva: { immer: true, }
  • 如需兼容 IE11,需配置 { immer: { enableES5: true }}

model

model规范:符合以下规则的文件会被认为是 model 文件
src/models 下的文件
src/pages 下,子目录中 models 目录下的文件
src/pages 下,所有 model.ts 文件

models/home.js

  1. export default {
  2. namespace: 'home',
  3. state: {
  4. dataSource: [],
  5. title: '',
  6. },
  7. reducers: {
  8. save(state, action) {
  9. return {...state, ...action.payload};
  10. },
  11. },
  12. effects: {
  13. *login({ payload }, { call, put }) {
  14. try {
  15. const { code, userinfo } = yield call(loginReq, payload);
  16. localStorage.setItem('userinfo', JSON.stringify(userinfo));
  17. // 触发reducers更新状态
  18. // 犹如import { call, put, takeEvery } from 'redux-saga/effects'中的takeEvery
  19. yield put({
  20. type: 'init',
  21. payload: userinfo,
  22. });
  23. history.push('/');
  24. } catch (error) {
  25. console.log(error);
  26. }
  27. },
  28. }
  29. }

model注册

自己写的model,umi会自动将其按照,命名空间的名称加入到全局变量里面

  • 开启dva的热跟新,在组件中引用,就直接可以从umi中引出自己定义的model
  • umi会将 models下的文件,已命名空间的方式,加入到 dva 的 connect里面

组件

useStore

在组件导入中将useSelector, useDispatch 导入
useStore.jpg

  1. import React, { useState, useEffect } from 'react'
  2. import { connect, useDispatch, useStore, useSelector } from 'umi';
  3. function App() {
  4. const dispatch = useDispatch();
  5. // 与redux使用方法相似,store为所有的model模块,详细见下图
  6. const state = useSelector(store => store.home);
  7. function onClick() {
  8. // home 是model的唯一namespace,save是其reducers中方法
  9. dispatch({
  10. type: 'home/save',
  11. payLoad: { name: 'lucy' }
  12. });
  13. }
  14. return (
  15. <div>
  16. <button onClick={onClick}>改变state中的值</button>
  17. </div>
  18. );
  19. }
  20. export default App;

connect

  1. import React, { useState, useEffect } from 'react';
  2. import {object} from 'prop-types';
  3. import { connect } from 'umi';
  4. import { TabList } from '@/components';
  5. Dashboard.propTypes = {
  6. state: object.isRequired,
  7. };
  8. function Dashboard({state, _$init}) {
  9. const [tabKey, setTabKey] = useState('');
  10. useEffect(() => { _$init() }, []);
  11. function tabChange(key) {
  12. setTabKey(key);
  13. }
  14. const TabListProps = {
  15. type: 'card',
  16. value: tabKey,
  17. dataSource: tabSource,
  18. onChange: tabChange,
  19. }
  20. return (
  21. <div>
  22. <TabList {...TabListProps} />
  23. </div>
  24. );
  25. }
  26. function mapStateToProps(state) {
  27. // console.log('state', state)
  28. return {
  29. state: state.dashboard
  30. }
  31. }
  32. function mapDispatchToProps(dispatch) {
  33. return {
  34. _$init: payload => dispatch({payload, type: 'dashboard/init'})
  35. }
  36. }
  37. export default connect(mapStateToProps, mapDispatchToProps)(Dashboard);