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. Django面试集锦(51-65)

    目录 51.Django中filter和exclude的区别? 52.Django中values和values_list的区别? 53.如何使用django orm批量创建数据? 54.Django的 ...

  2. C语言I作业1

    1 你对软件工程专业或计算机科学与技术专业了解是怎样的? 软件工程顾名思义就是工程化的方法生产软件的一门学科.涉及到程序设计语言,数据库,软件开发工具,系统平台,标准,设计模式等方面. 2 你了解c语 ...

  3. CassandraAppender - distributed logging,分布式软件logback-appender

    农历年最后一场scala-meetup听刘颖分享专业软件开发经验,大受启发.突然意识到一直以来都没有完全按照任何标准的开发规范做事.诚然,在做技术调研和学习的过程中不会对规范操作有什么严格要求,一旦技 ...

  4. LeetCode 200. Number of Islands 岛屿数量(C++/Java)

    题目: Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is s ...

  5. Linux/UNIX编程:获取指定用户所有正在运行的进程ID和进程名

    先用系统函数 `getpwnam` 获得指定用户名的 UID,然后遍历 /proc/ 中所有 PID 目录,如果 /proc/PID/status 中的 UID 是输入用户名对应的 UID 则输出该 ...

  6. HDU 1004 Let the Balloon Rise(STL初体验之map)

    Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...

  7. ELK搭建(docker环境)

    ELK是Elasticsearch.Logstash.Kibana的简称,这三者是核心套件,但并非全部. Elasticsearch是实时全文搜索和分析引擎,提供搜集.分析.存储数据三大功能:是一套开 ...

  8. 威联通(NAS)搭建个人图床

    名词解释: 图床:一般是指储存图片的服务器,有国内和国外之分.国外的图床由于有空间距离等因素决定访问速度很慢影响图片显示速度.国内也分为单线空间.多线空间和cdn加速三种. 更详细的内容,请左转查看百 ...

  9. 如何在windows10家庭版上搭建docker

    如何在windows10家庭版上搭建docker 建议先跳到最后一条,看完之后再决定是否安装. 0X00搭建原因 首先搭docker的想法是我在复现漏洞时候,发现大佬们的复现环境都是基于docker的 ...

  10. Imagine— 让图片再小一点点

    文章选自我的博客:https://blog.ljyngup.com/archives/267.html/ 再次祭出神奇的Github 这次给大家介绍的是一款神奇的图片压缩软件,以质量的微小损失换取大量 ...