快速上手
信息
目前useRequest的版本代码为v3. 故不再内置Taro.request. 若从1.x迁移用户请注意
useRequest
是一个强大的异步数据管理的 Hooks,Taro 项目中的网络请求场景使用 useRequest
就够了。
useRequest
通过插件式组织代码,核心代码极其简单,并且可以很方便的扩展出更高级的功能。目前已有能力包括:
- 自动请求/手动请求
- 轮询
- 防抖
- 节流
- 屏幕聚焦重新请求
- 错误重试
- loading delay
- SWR(stale-while-revalidate)
- 缓存
接下来让我们先从两个最简单的例子认识 useRequest
。
默认用法
useRequest
的第一个参数是一个异步函数,在组件初次加载时,会自动触发该函数执行。同时自动管理该异步函数的 loading
, data
, error
等状态。
- React
- Vue
const { data, error, loading } = useRequest(getUsername);
<template>
<block>
<view>{{request.loading}}</view>
<view>{{request.data}}</view>
<view>{{request.error}}</view>
</block>
</template>
<script>
export default {
setup() {
// 由于要保证request内部的变量不失活。 这里简单的可以将request直接抛出
const request = useRequest(getUsername);
return {
request,
};
},
};
</script>
- React
- Vue
network/useRequest/basic/index
import React from 'react';
import { View } from '@tarojs/components';
import DemoContent from '@src/components/DemoContent';
import { useRequest } from 'taro-hooks';
import Mock from 'mockjs';
function getUsername(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve(Mock.mock('@name()'));
} else {
reject(new Error('Failed to get username'));
}
}, 1000);
});
}
export default () => {
const { data, error, loading } = useRequest(getUsername);
return (
<DemoContent title="Basic - 默认用法" desc="读取用户名称">
{error ? (
<View>{error.message}</View>
) : loading ? (
<View>loading...</View>
) : (
<View>Username: {data}</View>
)}
</DemoContent>
);
};
network/useRequest/basic/index
<template>
<block>
<demo-content title="Basic - 默认用法" desc="读取用户名称">
<view v-if="request.loading"> loading... </view>
<template v-else>
<view v-if="request.error"> error: {{ request.error.message }} </view>
<view v-else> Username: {{ request.data }} </view>
</template>
</demo-content>
</block>
</template>
<script>
import { useRequest } from 'taro-hooks';
import Mock from 'mockjs';
function getUsername() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve(Mock.mock('@name()'));
} else {
reject(new Error('Failed to get username'));
}
}, 1000);
});
}
export default {
setup() {
const request = useRequest(getUsername);
return { request };
},
};
</script>
手动触发
如果设置了 options.manual = true
,则 useRequest 不会默认执行,需要通过 run
来触发执行。
- React
- Vue
const { loading, run } = useRequest(changeUsername, {
manual: true,
});
<template>
<block>
<view @click="request.run()">{{request.loading}}</view>
<view>{{request.data}}</view>
</block>
</template>
<script>
export default {
setup() {
// 由于要保证request内部的变量不失活。 这里简单的可以将request直接抛出
const request = useRequest(changeUsername, {
manual: true,
});
return {
request,
};
},
};
</script>
- React
- Vue
network/useRequest/basic/manualRun
import React from 'react';
import DemoContent from '@src/components/DemoContent';
import { Button, Input, Field } from '@taroify/core';
import { showToast } from '@tarojs/taro';
import { useState } from '@taro-hooks/core';
import { useRequest } from 'taro-hooks';
function editUsername(username: string): Promise<void> {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve();
} else {
reject(new Error('Failed to modify username'));
}
}, 1000);
});
}
export default () => {
const [state, setState] = useState('');
const { loading, run } = useRequest(editUsername, {
manual: true,
onSuccess: (result, params) => {
setState('');
showToast({
title: 'The username was changed to "${params[0]}" !',
icon: 'success',
});
},
onError: (error) => {
showToast({ title: error.message, icon: 'error' });
},
});
return (
<DemoContent
title="Basic - 手动触发"
desc="在这个例子中,我们通过 run(username) 来修改用户名,通过 onSuccess 和 onError 来处理成功和失败"
>
<Field align="center">
<Input
onChange={(e) => setState(e.detail.value)}
value={state}
placeholder="Please enter username"
/>
<Button
disabled={loading}
loading={loading}
color="primary"
size="small"
onClick={() => run(state)}
>
{loading ? 'Loading' : 'Edit'}
</Button>
</Field>
</DemoContent>
);
};
network/useRequest/basic/manualRun
<template>
<block>
<demo-content
title="Basic - 手动触发"
desc="在这个例子中,我们通过 run(username) 来修改用户名,通过 onSuccess 和 onError 来处理成功和失败"
>
<nut-input
:disabled="request.loading"
v-model="state"
placeholder="Please enter username"
>
<template #button>
<nut-button
:loading="request.loading"
size="small"
type="primary"
shape="square"
@click="request.run(state)"
>{{ request.loading ? 'Loading' : 'Edit' }}</nut-button
>
</template>
</nut-input>
</demo-content>
</block>
</template>
<script>
import { showToast } from '@tarojs/taro';
import { useState } from '@taro-hooks/core';
import { useRequest } from 'taro-hooks';
function editUsername() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve();
} else {
reject(new Error('Failed to modify username'));
}
}, 1000);
});
}
export default {
setup() {
const [state, setState] = useState('');
const request = useRequest(editUsername, {
manual: true,
onSuccess: (result, params) => {
setState('');
showToast({
title: 'The username was changed to "${params[0]}" !',
icon: 'success',
});
},
onError: (error) => {
showToast({ title: error.message, icon: 'error' });
},
});
return {
request,
state,
};
},
};
</script>
上面两个例子,我们演示了 useRequest
最基础的用法,接下来的我们开始逐个详细介绍 useRequest
的特性。