寫一個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

相關文章
相關標籤/搜索