Umi 通常会搭配 Dva 使用,用于管理页面状态和逻辑

一、注册 model

首先需要在 .umirc.js 中启用 dva 插件

export default {
plugins: [
['umi-plugin-react', {
dva: {
immer: true,
},
}],
],
}

dva 通过 model 的概念把一个模型管理起来,相当于其他状态管理工具中的 store,通常由以下组成

export default {
namespace: '', // 表示在全局 state 上的 key
state: {}, // 状态数据
reducers: {}, // 管理同步方法,必须是纯函数
effects: {}, // 管理异步操作,采用了 generator 的相关概念
subscriptions: {}, // 订阅数据源
};

在 umi 中会按照约定的目录来注册 model,且文件名会被识别为 model 的 namespace

model 还分为 src/models/*.js 目录下的全局 model,和 src/pages/**/models/*.js 下的页面 model

然后在 src/pages/ 下的页面文件中通过 connect 关联对应的 model

import React, { Component } from 'react';
import { connect } from 'dva';
class PageView extends Component {
render() {
return <div>
<h1>PageView for Dva.Model</h1>
</div>
}
};

// 这里的 pageModel 是对应 model 的 namespace
const mapStateToProps = ({ pageModel }) => {
return { ...pageModel };
}; export default connect(mapStateToProps)(PageView);

上面的 mapStateToProps 方法会将对应 model 中的 state 映射到 props

它接受的第一个参数是所有可以使用的 state,即全局 model 和当前页面 model 的 state,需要通过 namespace 区分

二、简单上手

假如有这样的 model:

经过 connect 之后,可以在页面上可以直接通过 props 获取到 state

如果需要修改 state 的值,可以在 reducers 中添加一个函数

然后在页面上通过 dispatch 调用

被 connect 的 Component 会自动在 props 中拥有 dispatch 方法

它需要一个包含 typepayload 的对象作为入参

其中 type 是需要调用的方法名,可以是 reducer 或者 effect,不过需要添加对应 model 的 namespace

payload 是需要传递的信息,可以在被调用的方法中接收

从这里可以看出,只要 State 有变化,视图层就会自动更新

这里就需要介绍一下 dva 的五个核心元素:

State:一个对象,保存整个应用状态

View:React 组件构成的视图层

Action:一个对象,描述事件

connect 方法:一个函数,绑定 State 到 View

dispatch 方法:一个函数,发送 Action 到 State

在 Dva 中,State 是储存数据的地方,我们通过 dispatch 触发 Action,然后更新 State。

如果有 View 使用 connect 绑定了 State,当 State 更新的时候,View 也会更新。

三、异步函数

Dva 中的异步操作都放到 effects 中管理,基于 Redux-saga 实现

Effect 是一个 Generator 函数,内部使用 yield 关键字,标识每一步的操作

每一个 effect 都可以接收两个参数:

1. 包含 dispatch 携带参数 payload 的 action 对象

2. dva 提供的 effect 函数内部的处理函数集

第二个参数提供的处理函数中,常用的有 call、put、select

call: 执行异步函数

put: 发出一个 Action,类似于 dispatch

select: 返回 model 中的 state

完整的示例:

import * as services from '@/services';
export default {
namespace: 'pageModel',
state: {
title: 'Welcome to Wise.Wrong\'s Bolg',
name: 'wise'
},
effects: {
*testEffect({ payload }, { call, put, select }) {
// 获取 state 中的值
const { name } = yield select(state => state.pageModel);
// 接口入参
const params = { name, ...payload };
// services.getInfo 是封装好的请求
const { data } = yield call(services.getInfo, params);
// 请求成功之后,调用 reducer 同步方法更新 state
yield put({
// 调用当前 model 的 action 不需要添加 namespace
type: 'changeTitle',
payload: data,
});
}
},
reducers: {
changeTitle(state, { payload }) {
return {
...state,
title: payload
};
},
},
};

四、常见问题

1. 在 effects 中,如何同步调用两个异步函数?

如果在一个 effect 中,函数 B 的入参需要依赖于函数 A 的执行结果,可以使用 @@end 来阻塞当前的函数

2. 在 model 中使用 router ?

在 model 中引入 umi/router 即可

import router from 'umi/router';

...
router.push(`?${qs.stringify(search)}`);

3. 全局 layout 使用 connect 后路由切换不更新页面

需用 withRouter 高阶一下,注意顺序

import withRouter from 'umi/withRouter';

const mapStateToProps = (state) => {
// ...
}; export default withRouter(connect(mapStateToProps)(Layout));

Umi 小白纪实(二)—— model 的注册与使用的更多相关文章

  1. Umi 小白纪实(三)—— 震惊!路由竟然如此强大!

    在<Umi 小白纪实(一)>中有提到过简单的路由配置和使用,但这只是冰山一角 借用一句广告词,Umi 路由的能量,超乎你的想象 一.基本用法 Umi 的路由根结点是全局 layout  s ...

  2. Umi 小白纪实(一)—— 创建项目&常用配置

    umi 是一个企业级 react 应用框架,也是蚂蚁金服的底层前端框架 <蚂蚁金服的前端框架和工程化实践> 一.安装脚手架 在创建项目之前,需要保证有 node 8.10 以上的环境 可以 ...

  3. HTML 事件(二) 事件的注册与注销

    本篇主要介绍HTML元素事件的注册.注销的方式. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流.事件委托 4. ...

  4. node.js 初学(二)—— 搭建注册/登录服务器

    node.js 初学(二)—— 搭建注册/登录服务器 理论上来说,代码实现在理论和实际上是一样的.但实际上来说,他们不是 做一个最简单的用户注册登录功能 1.接口定义: 注册:/user?act=re ...

  5. SpringCloud实战之初级入门(二)— 服务注册与服务调用

    目录 1.环境介绍 2.服务提供 2.1 创建工程 2.2 修改配置文件 2.3 修改启动文件 2.5 亲测注意事项 3.服务调用 3.1 创建工程 3.2 修改配置文件 3.3 修改启动文件 3.4 ...

  6. SpringCloud(二)- 服务注册与发现Eureka

    离上一篇微服务的基本概念已经过去了几个月,在写那篇博客之前,自己还并未真正的使用微服务架构,很多理解还存在概念上.后面换了公司,新公司既用了SpringCloud也用了Dubbo+Zookeeper, ...

  7. 【Spring Cloud学习之二】服务注册和发现

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 Spring Cloud 1.2 一.EurekaEureka是Netflix开源的一个RESTful服务,主要用于服 ...

  8. 玩转springcloud(二):注册中心-Eureka

    一.简介 注册中心 注册中心是服务发现的核心.它保存了各个可用服务实例的网络地址(IP Address和Port).服务注册中心必须要有高可用性和实时更新功能. Netflix Eureka 就是一个 ...

  9. Dubbo系列之 (二)Registry注册中心-注册(2)

    引导 本章主要介绍下AbstractRegistry.FailbackRegistry的作用和源码. AbstractRegistry 首先,直接引出这个类的作用,该类主要把服务提供者信息缓存本地文件 ...

随机推荐

  1. C语言系列之实验楼笔记(一)

    创建C程序的几个过程: 1.编辑:创建和修改C程序的源代码 2.编译:编译器可以将源代码转成机器语言.linux 这些文件扩展名.o 3.链接:通过一次完成编译和链接 4.执行;运行程序 打开xfce ...

  2. MySQL物理物理备份与还原工具xtraBackup

    (一)xtraBackup简介 xtraBackup是Percona公司开发的一款MySQL数据库备份软件,在备份模式中属于物理备份.其显著特点是开源.免费.备份执行过程中不会阻塞事物.备份可压缩.支 ...

  3. 全局对象的构造函数会在main函数之前执行?

    #include <iostream> using namespace std; class CTest { public: CTest() { cout << "构 ...

  4. 实现理论上无tps上限的分布式压测(基于Jmeter+InfluxDB+Grafana+Spring Boot)

    JMeter自身带有Master-Slave压测框架,对于并发量不是很高的压力情况下(比如tps低于5000),该方案是可行的,并且使用起来非常方便,只要在配置文件或者命令行工具的参数做一些补充,即可 ...

  5. 杭电-------2041超级楼梯(c语言写)

    /* 当未走的楼梯大于1时,可以选择走一步或者走两步,每次所做的选择相似, 符合分治法的特性,因此选择分治法,又测试用例有多组,为了避免多组 用例的重复计算,可用一个数组将已经知道的剩下的楼梯可以走的 ...

  6. React中使用 PropTypes 进行类型检查

    官方文档学习链接:https://zh-hans.reactjs.org/docs/typechecking-with-proptypes.html import React, { Component ...

  7. 珠峰-webpack1

    #### sourcemap #### watch 选项 #### 3个常用的小插件. #### 前端webpack的自己的mock #### 服务端引用了webpack的插件. #### resol ...

  8. 珠峰-vue

  9. windows下修改tomcat的startup.bat脚本文件后台运行

    1.修改startup.bat文件 rem Get remaining unshifted command line arguments and save them in the set CMD_LI ...

  10. SpringBoot图文教程7—SpringBoot拦截器的使用姿势这都有

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...