写一个react hook:useLoading

在写业务的过程当中,咱们老是会遇到这样的需求,在请求时显示一个 loading,而后请求结束后展现数据。以一个是否是 vip 的场景为例,若是不加入 loading 状态,页面可能在未请求的时候显示非 vip,数据请求完成以后,发现是 vip,再改为 vip。这样无疑体验较差,可是咱们又不但愿一直使用 useState 来声明 loading 状态,这无疑是乏味的:react

const [loading, setLoading] = useState(false);
...

因此,不如使用 hooks 来封装这部分逻辑,来实现一个 useLoading hook。ajax

在写这个 hook 以前,咱们要先理清楚这个 hook 的入参和出参。咱们但愿这个 hook 有这样的效果,咱们传入一个请求的函数,获得这个函数是否在 loading,以及一个包装后的请求函数。代码以下:api

const [isLoading, wrappedAjax] = useLoading(ajax);

实现

直接上代码:app

import { useState, useCallback } from "react";
export default function useLoading(req) {
  const [loading, setLoading] = useState(false);
  const wrapReq = useCallback(
    (...args) => {
      setLoading(true);
      return req(...args).then((data) => {
        setLoading(false);
        return Promise.resolve(data);
      }).catch((reason) => {
      	setLoading(false);
        return Promise.reject(reason);
      });
    },
    [req]
  );
  return [loading, wrapReq];
}

代码也很简单,就是对原先的 api 请求进行了包装,在调用前,设置 loading 为 true,拿到数据以后,设置 loading 为 false。调用方式以下:ide

const [loading, req] = useLoading(checkVip);
  useEffect(() => {
    req().then(({ vip }) => {
      console.log(vip);
      setVip(vip);
    }).catch((err) => alert(err));
  }, [req]);

下面是一个简单的 demo(没看到效果请点击刷新按钮)。能够看到,当不设置 loading 状态的时候,页面是由 no vip 跳到 vip 的,体验是比较差的。函数

why not React Query

当咱们只是须要一个 loading 状态,而又不想写重复的 useState 来管理 loading 状态时,上面这个小 hook 就显得更轻量了。可是若是须要一整套完整的解决方案,使用 React Query 则是更好的选择。(本文完)spa

相关文章
相关标签/搜索