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,包括密码加盐处理、记住密码、自动...