import { useState } from "react";
interface State<D> {
// 定义异步请求状态的接口
data: D | null;
error: Error | null;
stat: "idle" | "loading" | "error" | "success"; // idle 表示未发生异步操作
}
const defaultInitialState: State<null> = {
// 默认状态
error: null,
data: null,
stat: "idle",
};
const defaultInitialConfig = {
throwOnError: false, // 默认为不手动抛出异常,而是直接返回 error
};
/**
* 管理异步状态的自定义 hook
* @param 异步操作函数: Promise
* @returns 异步获取的数据以及各种状态
*/
export const useAsync = <D>(
initialState?: State<D>,
intialConfig?: typeof defaultInitialConfig
) => {
const config = { ...defaultInitialConfig, ...intialConfig };
const [state, setState] = useState<State<D>>({
...defaultInitialState,
...initialState,
});
const setData = (data: D) =>
setState({
// 异步请求成功的处理
data,
error: null,
stat: "success",
});
const setError = (
error: Error //这里的 error 只能在纯异步情况下使用,因为其本质是 useState,而 useState 是异步的
) =>
setState({
// 异步请求失败的处理
data: null,
stat: "error",
error,
});
const run = (promise: Promise<D>) => {
// run 用于触发异步请求,一般传入网络请求函数
if (!promise || !promise.then) {
// 如果没传入参数或传入的不是 Promise,报错
throw new Error("请传入 Promise 类型数据"); // throw Error 会打断一切的进程,下面的代码也不会运行
}
setState({ ...state, stat: "loading" }); // 异步操作中,把状态设置为 loading
return promise
.then((data) => {
setData(data);
return data; // 这里可返回 data,也可不返回 data
})
.catch((error) => {
setError(error);
if (config.throwOnError) {
return Promise.reject(error); // catch 会内部消化异常,外部不能通过 try catch 等方式捕获异常,因此这里要手动抛出异常
}
return error;
});
};
return {
isIdle: state.stat === "idle",
isLoading: state.stat === "loading",
isError: state.stat === "error",
isSuccess: state.stat === "success",
run,
setData,
setError,
...state,
};
};
用自定义 hook 管理异步请求、状态
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 基于StatusLayout1.0的功能进行了一次改进和调整,更好去适应业务场景减少工作,高自由定制不局限于Loa...
- StatusLayout : 一个超高自定义度又简单的页面状态管理库 业务场景需求: 在日常开发App的过程中,...
- 前言 在Android开发中我们经常遇到这样的场景:去加载网络数据时需要显示进度条,提示用户正在加载,加载失败需要...
- 导入依赖 springboot配置类 在springboot项目中配置shiro,包括密码加盐处理、记住密码、自动...