跳到主要内容
版本:v3

自动管理请求状态

策略类型

use hook

useRequest 表示一次请求的发送,调用时默认将发送一次请求,在企业级项目中,在视图中展示数据的传输状态非常重要。在页面获取初始数据或提交数据时,useRequest 是最常用的 use hook 之一。

使用

它的基础用法已在基础-结合 UI 框架中详细介绍。

设置初始数据

data 在请求成功前默认为 undefined,但有时候我们需要 data 在请求成功前也有初始值,例如在请求列表时通常需要将它初始化为[],否则在渲染视图时会因为无法循环渲染而导致报错。

const { data } = useRequest(todoListGetter, {
// 请求响应前,data的初始值
initialData: []
});

也可以将initialData设置成函数动态设置初始值,例如,当你不希望应用每次进入时都显示 Loading 图标,而希望使用旧数据替代时,你可以返回旧数据作为初始值,它的体验比 Loading 更好。

const { data, loading, error } = useRequest(todoListGetter, {
initialData() {
// 设置上一次的响应数据
const storedData = localStorage.getItem('placeholder-data');
return JSON.parse(storedData || '{}');

// 也使用alova的level2存储适配器
// return alovaInst.l2cache.get('placeholder-data');
}
}).onSuccess(({ data, method }) => {
// 保存响应数据
localStorage.setItem('placeholder-data', JSON.stringify(data));

// 也使用alova的level2存储适配器
// alovaInst.l2cache.set('placeholder-data', data);
});

不立即发送请求

设置immediatefalse避免立即请求。

const { data } = useRequest(todoListGetter, {
immediate: false
});

强制请求

强制请求是指绕过缓存的检查触发请求发送的机制,当需要在一定条件下获取最新的数据时很有用。

useRequest(todoListGetter, {
force: true
});

也可以设置为函数,当函数返回值为true时,强制请求。

useRequest(todoListGetter, {
force: ({ method, args }) => {
return !!args[0];
}
});

手动发送请求

useRequest的第一个参数设置为函数。

const {
// ...
// 手动发送器请求的函数,调用后发送请求
send

// 在这边将会接收到 send 函数的参数
} = useRequest(newTodo => alovaInstance.Post('/todo', newTodo), {
// 当immediate为false时,默认不发出
immediate: false
});

send({
/* todo data */
});

send函数可以让你自由地重复发起请求。

在 react 中,send 函数使用了useCallback包裹,同时它也不受闭包陷阱限制,你可以直接在事件中使用它,不用担心引起性能问题。

useRequestuseWatcher中我们都可以调用send函数手动触发请求,send 函数触发请求时候,可以传入任意多个参数,这些参数其实可以分别被以下 3 个位置接收。

调用send支持传入任意多个参数,这些参数可以在以下 3 个位置接收。

在 method handler 中接收

当它们的第一个参数设置为回调函数时可以接收到,这通常在删除列表项时很有用,具体如下:

const { send } = useRequest(id =>
// id将接收到1
removeTodoPoster(id)
);
send(1);

在事件回调函数中接收

在事件回调函数中通过event.args接收,它是一个包含了 send 函数的所有参数的数组。

const { send, onSuccess, onError, onComplete } = useRequest(newTodo =>
alovaInstance.Post('/todo', newTodo)
);
onSuccess(event => {
// args的值为[1]
console.log(event.args);
});
onError(event => {
// args的值为[1]
console.log(event.args);
});
onComplete(event => {
// args的值为[1]
console.log(event.args);
});

// 发送请求
send(1);

在 force 函数中接收

force 用于指定是否需要穿透响应缓存,关于响应缓存的内容将在后面的缓存模式中讲解。

const { send } = useRequest(alovaInstance.Get('/todo'), {
force: event => {
return event.args[0];
}
});
send(1);

下载和上传进度

通过downloadinguploading可以获得下载和上传的进度信息,你可以直接在视图中展示进度信息。

const { downloading } = useRequest(alovaInstance.Get('/todo/downloadfile'));
const { uploading } = useRequest(alovaInstance.Get('/todo/uploadingfile'));

downloadinguploading的数据格式如下:

export type Progress = {
total: number;
loaded: number;
};

中断请求

通过 useHook 接收abort用于手动中断请求。

const {
// ...
// abort函数用于中断请求
abort
} = useRequest(todoListGetter);

abort();

额外的管理状态

设置额外的管理状态,这些状态可以实现跨组件更新,具体请查看额外的管理状态

中间件

通过useRequest的中间件几乎能控制一个请求的所有行为,例如你可以使用它阻止请求。

let allowRequest = false;
useRequest(todoListGetter, {
middleware(ctx, next) {
if (!allowRequest) {
return;
}
return next();
}
});

具体请查看深入客户端-中间件

API

请查看API-useRequest