简单的全局异步状态管理
作者:互联网
总结一下学习的成果,在不借助框架的前提下构建一个简单、完整的项目还是需要不断地学习和总结的。
全局异步状态管理模块
此模块用于管理异步请求的状态,可以实现对单个请求的状态变化跟踪,短小精悍,用来练手感觉还不错,记录一下方便以后反复回过头学习。
- 新建useAsync cutome hook
import { useState } from "react"; export const useAsync = () => { ... }
- 声明状态接口以及默认状态配置
interface State<D> { data: D | null; stat: "idle" | "loading" | "success" | "error"; error: Error | null; } const defaultInitialState: State<null> = { data: null, stat: "idle", error: null, }; export const useAsync = <D>(initialState?: State<D>) => { const [state, setState] = useState<State<D>>({ ...defaultInitialState, ...initialState, }); }
useAsync支持在创建时传入initialState用于初始化状态。
- 主要逻辑
基本功能概括起来就三个:(1)运行指定的Promise;(2)设置状态;(3)传出状态。
根据功能,创建以下函数:
// 设置success状态 const setData = (data: D) => { setState({ data, stat: "success", error: null, }); }; // 设置error状态 const setError = (error: Error) => { setState({ error, stat: "error", data: null, }); }; const run = (promise: Promise<D>) => { // 判断是否是promise对象 if (!promise || !promise.then) { throw new Error("请传入正确的 Promise 对象"); } // 设置loading状态 setState({ ...state, stat: "loading" }); return promise .then((data) => { setData(data); return data; }) .catch((err) => { setError(err); return err; }); }; return { isIdle: state.stat === "idle", isError: state.stat === "error", isSuccess: state.stat === "success", isLoading: state.stat === "loading", run, setData, setError, ...state, };
- 用法
例如在登录页面,点击登录后的handleSubmit中:
export const LoginScreen = () => { const login = (...) => { ... }; const { run, isLoading, error } = useAsync(); const handleSubmit = async (values: { username: string; password: string; }) => { await run(login(values)); }; return ( <LongButton loading={isLoading}>登录</LongButton> ); };
首先调用useAsync(),获取run、isLoading等。run用于执行异步请求,isLoading会响应式的传出useAsync内部状态,LongButton的loading prop接收isLoading,用于判断状态。
效果: - 值得注意的地方
需要提醒的是,useAsync中状态的变化是异步的,即promise的执行是异步的,setState也是异步的,当需要有,这同步的状态判断需求时无法使用useAsync。
一个比较典型的例子,例如在注册页面,需要输入两次密码错误,在handleSubmit时判断是否错误,这种状态判断(或者错误判断)是同步的,因此就无法使用useAsync。
标签:异步,stat,const,状态,简单,error,全局,data,useAsync 来源: https://www.cnblogs.com/wananniannian/p/16671896.html