如何在React中使用Mock

mock官网的介绍:生成随机数据,拦截 Ajax 请求。使用mock生成模拟数据有这样的好处:

mock官网的介绍:生成随机数据,拦截 Ajax 请求。使用mock生成模拟数据有这样的好处:

❄让前后端分离,可以在不使用接口的时候也能生成动态数据。

❄防止第三方接口失效,在调用第三方接口的时候,今天还开着,有可能明天就被关了/(ㄒoㄒ)/~~。所以可以使用mock-server来模拟接口返回数据。

类似mock的还有百度的 yapi,阿里的 rap2, 大搜车的 easy-mock

本文将使用三种方法来请求mock,一种直接调用axios中的方法,一种原生的promise+xhr,一种在前面的基础上使用async/ await。

附上demoGitHub的地址

安装依赖

1
2
yarn add mockjs
yarn add axios

文件目录

|—data.js

|—mock.js

|—index.js

data中设置mock的请求路径,请求方法,还有一些模拟数据。mock作为组件发送请求,需要注意的是data需要挂载到index上,不然mock访问不到的。index是入口文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//data.js
import Mock from 'mockjs'
export default Mock.mock(/getdata/,'get',{
success:true,
message:'@image',
'list|1-3': [{
// 属性 sid 是一个自增数,起始值为 1,每次增 1
'sid|+1': 1,
// 属性 userId 是一个5位的随机码
'userId|5': '',
// 属性 sex 是一个bool值
"sex|1-2": true,
// 属性 city对象 是对象值中2-4个的值
"city|2-4": {
"110000": "北京市",
"120000": "天津市",
"130000": "河北省",
"140000": "山西省"
},
//属性 grade 是数组当中的一个值
"grade|1": [
"1年级",
"2年级",
"3年级"
],
//属性 guid 是唯一机器码
'guid': '@guid',
//属性 id 是随机id
'id': '@id',
//属性 title 是一个随机长度的标题
'title': '@title()',
//属性 paragraph 是一个随机长度的段落
'paragraph': '@cparagraph',
//属性 image 是一个随机图片 参数分别为size, background, text
'image': "@image('200x100', '#FFC0CB', 'Hello')",
//属性 address 是一个随机地址
'address': '@county(true)',
//属性 date 是一个yyyy-MM-dd 的随机日期
'date': '@date("yyyy-MM-dd")',
//属性 time 是一个 size, background, text 的随机时间
'time': '@time("HH:mm:ss")',
//属性 url 是一个随机的url
'url': '@url',
//属性 email 是一个随机email
'email': '@email',
//属性 ip 是一个随机ip
'ip': '@ip',
//属性 regexp 是一个正则表达式匹配到的值 如aA1
'regexp': /[a-z][A-Z][0-9]/,
}]
})

使用axios来发送请求

axios是一个基于promise的跨浏览器和nodejs的HTTP客户端,在这里使用get方法来发送请求,获取数据。写在componentDidMount中,当React插入组件到DOM后,里面的方法被调用一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//mockjs
import React from 'react'
import axios from 'axios'
class Mock extends React.Component {
constructor(props) {
super(props)
this.state = {
gData: null
}
}
componentDidMount() {
this.getData()
}
getData = () => {
axios.get('/getdata', {
params: {
image: ('200x100', '#FFF', 'Mock.js')
}
})
.then((res) => {
this.setState({
gData: res.data.message
})
})
.catch((err) => {
console.log(err)
})
}
render() {
return (
<div>
<img src={this.state.gData} />
<button onClick={this.getData}>点击获取(Get)Mock数据</button>
</div>
)
}
}
export default Mock

不过一开始,在这里报了一个错:

1
2
3
Failed to compile
src\mock.js
Line 14:5: 'getData' is not defined no-undef

因为我是这样写的。。。。

1
2
3
4
5
componentDidMount() {
getData = () => {
...
}
}

在componentDidMount中直接写方法报错的原因不太清楚,不过正确的写法有两种,一种是上面直接调用this.getData方法,另一种是直接aixos.get,不过这样就只是在初始时会请求数据。

使用promise+xhr来实现ajax

写这个也没有别的意思,加强一下基础💪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//mockjs
componentDidMount() {
this.getData()
}
getData = () => {
this.ajax('/getdata')
.then(
(res) => {
this.setState({
gData: res.message
})
})
.catch((err) => {
console.log(err)
})
}
ajax = (url) => {
var p = new Promise(function (res, rej) {
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) return
if (xhr.readyState == 4 && xhr.status == 200) {
//将返回json格式的内容转为对象
res(JSON.parse(xhr.response))
} else {
rej('error')
}}
xhr.open('get', url)
xhr.send(null)
})
return p
}

但是当我们需要发送多个ajax请求的时候,很多then的链式,代码有点回调地狱内味了(假设配置了/getdata1,/getdata2)

1
2
3
4
5
6
7
8
9
10
11
12
13
getData('/getdata')
.then(function(res){
console.log(res)
return queryData('/getdata1');
})
.then(function(res){
console.log(res);
return queryData('/getdata2');
})
.then(function(res){
console.log(res)
});

于是我们可以用async/ await 来改造一下

async/ await

是一个用同步的思维来解决异步问题的方案,async作为一个关键词放到普通函数前,表示函数是一个异步函数,不会阻塞后面代码的执行。然后等待await后面的函数运行完并有了返回结果后,继续执行。

1
2
3
4
5
6
7
8
9
10
getData = async () => {
try{
const res=await this.ajax('/getdata')
this.setState({
gData:res.message
})
}catch(err){
console.log(err)
}
}

需要注意的是,async的写法,一开始我是这样写的🙅‍

1
2
3
4
5
6
7
8
async getData(){
try{
...
})
}catch(err){
...
}
}

因为还是写在了componentDidMount,所以第一次请求是可以获得数据的,但是之后点击再调用了事件,就会报会这样的错

1
TypeError: Cannot read property 'ajax' of undefined

项目

在总结的过程中,被别人安利了安利 hooks,不用关注this和@umi/useRequest。下次再了解(下次一定下次一定

参考文章:

React中使用Mockjs进行接口数据模拟

React请求数据为什么要在componentDidMount方法里面做?

async/await基本理解及项目案例(结合Promise)

Mock接口依赖的使用

查看评论