1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        使用React Query做為axios請求庫的上層封裝

        共 7324字,需瀏覽 15分鐘

         ·

        2021-09-29 17:59

        前言

        在項目中,通常都需要跟服務端進行異步的數(shù)據(jù)交互,基本都是用到axios這個庫來做請求,嗯,畢竟擁有80k star,明星項目

        接下來,我們來回顧下axios在項目中的使用

        以查詢用戶信息為例,我們會這樣封裝

        async function requestUsers(){
          const {data} =await axios.get('/api/users');
          return data;
        }

        我們再用hooks再封裝下這個請求,包括loading等中間態(tài)的封裝,處理的優(yōu)雅一點

        import React, {useState,useEffect} from 'react';
        import axios from 'axios';
        function useUsersQuery(){
          const [data,setData] = useState([]);
          const [isLoading,setLoading] = useState(false);
          const [isError,setError] = useState(false)
          useEffect(()=>{
            (async()=>{
               setLoading(true);
               try{
                  const {data} = await axios.get('/api/users');
                  setData(data);
               } catch((()=>{
                  setError(true);
               })
               setLoading(false);
            })()
          })
          return { 
             data,
             isLoading,
             isError
          };
        }
        function UserList(){
          const {data, isLoading,isError} = useUsersQuery();
          if (isLoading) {
                return <div>loading</div>;
           }
          if (isError) {
                return <div>error</div>;
           }
          return (
            <div>
               {
                 data.map((item)=>{
                    return <div>{item.name}</div>
                 })
               }
            </div>

          )
        }

        可以看到,我們的項目中基本上是這樣封裝請求,我們不僅要請求數(shù)據(jù),還要處理相應的loading,error這些中間態(tài),這類通用的中間狀態(tài)處理邏輯可能在不同組件中重復寫很多次。

        另外,現(xiàn)在的前端項目特別是單頁面應用,會使用Flux、Redux、Mobox等狀態(tài)管理庫,會把組件間共享的數(shù)據(jù)都存放在狀態(tài)管理庫中,這些可以分為兩類,一類是用戶交互的中間狀態(tài),比如isLoading,isClose,modalVisible等等,另外一類就是服務端狀態(tài)(數(shù)據(jù))

        我們一般處理的方式都是無差別的存放在全局狀態(tài)管理上,狀態(tài)管理庫為了兼容異步請求,就有了redux-saga,redux-action這些異步解決方案

        其實對于redux等狀態(tài)管理庫,本身是沒有異步這個概念,只有mutation這種操作,為了支持異步,硬是強加了異步action這種操作,實際這些異步中間件就是在最后的請求回調(diào)透傳了dispatch,諸如這些情況,我們不僅將數(shù)據(jù)一鍋燉放在全局狀態(tài)管理上,寫法上也使得項目越來越臃腫了(以至于出現(xiàn)后面rematch、dva方案進行簡化),我們有沒有想過,服務端的狀態(tài)就不應該放在全局狀態(tài)管理上,全局狀態(tài)管理應該專門處理用戶交互的中間狀態(tài)

        接下來,就是引出今天的主角 React Query

        React Query

        React Query 通常被描述為 React 缺少的數(shù)據(jù)獲取(data-fetching)庫,但是從更廣泛的角度來看,它使 React 程序中的獲取,緩存,同步和更新服務器狀態(tài)變得輕而易舉。

        解決了什么問題

        服務端狀態(tài)有以下特點:

        1. 存儲在遠端,本地無法直接控制

        2. 需要異步 API 來查詢和更新

        3. 可能在不知情的情況下,被另一個請求方更改了數(shù)據(jù),導致數(shù)據(jù)不同步

        現(xiàn)有的狀態(tài)管理庫(如 Mobx、Redux等)適用于管理客戶端狀態(tài),但它們并不關心客戶端是如何異步請求遠端數(shù)據(jù)的,所以他們并不適合處理異步的、來自服務端的狀態(tài)。

        而 React Query 就是為了解決服務端狀態(tài)帶來的上述問題而出現(xiàn)的,除此之外它還帶來了以下特性:

        1. 更方便地控制緩存

        2. 把對于相同數(shù)據(jù)的多個請求簡化成一個

        3. 在后臺更新過期數(shù)據(jù)

        4. 知道數(shù)據(jù)什么時候會「過期」

        5. 對于數(shù)據(jù)的變化盡可能快得做出響應

        6. 分頁查詢和懶加載等請求性能優(yōu)化

        7. 管理服務器狀態(tài)的內(nèi)存和垃圾回收

        8. 通過結(jié)構(gòu)共享(structural sharing)來緩存查詢結(jié)果

        請求中間態(tài)處理

         function Todos({
           const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)

           if (isLoading) {
             return <span>Loading...</span>
           }

           if (isError) {
             return <span>Error: {error.message}</span>
           }

           // also status === 'success', but "else" logic works, too
           return (
             <ul>
               {data.map(todo => (
                 <li key={todo.id}>{todo.title}</li>
               ))}
             </ul>

           )
         }

        React query會自動把這些isLoading,isError請求中間態(tài)處理好,我們不必寫重復邏輯,另外配合Suspense提對一點對于loading場景的處理,Suspense也支持的不錯,特別是局部Loading,簡直Nice!

        ReactQuery 的狀態(tài)管理

        Fetch, cache and update data in your React and React Native applications all without touching any "global state".

        官網(wǎng)對于React Query的簡述,注意global state,你會不解,為什么React Query明明是一個請求庫,跟數(shù)據(jù)狀態(tài)管理又有什么關系,甚至可以處做全局狀態(tài)管理

        那是因為ReactQuery 會在全局維護一個服務端狀態(tài)樹,根據(jù) Query key 去查找狀態(tài)樹中是否有可用的數(shù)據(jù),如果有則直接返回,否則則會發(fā)起請求,并將請求結(jié)果以 Query key 為主鍵存儲到狀態(tài)樹中。

        ReactQuery 就將我們所有的服務端狀態(tài)維護在全局,并配合它的緩存策略來執(zhí)行數(shù)據(jù)的存儲和更新。借助于這樣的特性,我們就可以將所有跟服務端進行交互的數(shù)據(jù)從類似于 Redux 這樣的狀態(tài)管理工具中剝離,而全部交給 ReactQuery 來管理。

        舉個例子:

        import React from "react";
        import { useQuery, queryCache } from "react-query";
        import "./styles.css";

        export default function App({
          return (
            <div className="App">
              <h1>Shared state using react-query</h1>
              <Comp1 />
              <Comp2 />
            </div>

          );
        }

        function useSharedState(key, initialValue{
          const { data: state } = useQuery(key, () => queryCache.getQueryData(key), {
            initialData: initialValue
          });

          const setState = value => queryCache.setQueryData(key, value);

          return [state, setState];
        }

        function Comp1({
          const [count, setCount] = useSharedState("count"1);

          console.log("comp1 rendered");

          return (
            <div>
              <p>Count: {count}</p>
              <button onClick={() => setCount(count + 1)}>add</button>
            </div>

          );
        }

        function Comp2({
          const [count, setCount] = useSharedState("count"2);

          console.log("comp2 rendered");

          return (
            <div>
              <p>Count: {count}</p>
              <button onClick={() => setCount(count + 1)}>add</button>
            </div>

          );
        }

        上述方式是可以實現(xiàn)React Query狀態(tài)管理,但是有性能問題,其實本質(zhì)還是利用Context透傳,我們知道Context處理prop drilling問題,但是有性能問題,詳情可查看這篇文章 精讀《React — 5 Things That Might Surprise You》

        不過令人費解的是官方強調(diào)ReactQuery 的狀態(tài)管理,但是在官網(wǎng)例子并沒有給出類似的例子,上述例子還是在官方的github倉庫翻到

        作者說會在一個講座分析,后面我再深入研究,先留個坑

        參考文獻

        • https://react-query.tanstack.com/quick-start

        • https://github.com/tannerlinsley/react-query/discussions/489

        • https://github.com/tannerlinsley/react-query/discussions/329

        • https://tkdodo.eu/blog/react-query-as-a-state-manager


        瀏覽 60
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产精品毛片一区视频播| 精品国产成人a在线观看| 自拍偷拍激情视频| AV天堂偷拍亂伦| 永久免费一区二区三区| 水果派解说在线观看| 成人免费无码婬片在线| 东京热一区二区| 中文字幕不卡| 少妇被躁到高潮无码| 日韩天堂av| 亚洲一级二级三级| 一品国精和二品国精的文化意义| 色哟哟视频在线观看| 日本在线观看www| 成人日韩在线| 亚洲日韩欧美一区二区| 欧美熟妇精品黑人巨大一二三区| 国产精品久久久久野外| 色婷婷av| 天天操夜夜操视频免费高清 | 性欧美亚洲| 亚洲无吗在线播放| 色婷久久| 国产做受91一片二片老头| 69式荫蒂被添全过程频| 在线免费无码| 亚洲高清人妻| 国产探花一区二区三区| 高潮流水视频| 特级西西44www无码| 日韩一区二区三区四区| 欧美精品18videosex性欧美| 在线观看操逼| 亚洲无码www| 超碰人人操人人| 牛牛AV| 中文字幕特黄A片| 国产网站免费| 欧美在线免费观看| 激情六月天| 影视先锋久久| 亚洲成a人| x88AV吊钟奶熟女| 亚洲最大成人网站| 欧美亚洲成人网站| www免费视频| 亚洲国产爱| 无码-ThePorn| 国产青草视频在线观看| 国产中文字幕波多| 国产深夜福利| 99热精品在线观看| 无码视频一二三区| 欧美后门菊门交3p| jiujiuav| 九九九九AV| 国产伊人网| 国产熟妇婬乱A片免费看牛牛| 九九毛片| 亚洲综合一区二区三区| 久久久一| 97综合| 国产无码a| 五月天婷婷色色| 丰滿老婦BBwBBwBBw| 91色五月| 人人看人人色| 中文无码熟妇人妻AV在线| 中文成人在线| 久久成人三级片| 8050网午夜| 国产午夜福利电影| 亚洲AV无码成人精品区天堂小说| 国产成人自拍视频在线| 香蕉伊人视频| 操操影视| 91白丝喷水自慰网站| 一级黄色免费看| 高清无码免费在线| 久久精品三级视频| 欧美日韩成人在线观看| 天天干天天操天天| 国产精品免费久久| 91九色在线| 成人国产精品秘在线看| 男女福利视频| 日韩中文字幕久久| 亚洲精品无码永久| 99久久夜色精品国产亚洲| 国产高清视频在线观看| 亚洲激情综合视频| 黄色小视频在线免费看| 亚洲操逼视频| 成人性爱免费网站| 91人妻人人爽| 日韩三级片网址| 91福利在线视频| 中文字幕永久免费| 无码成人网| 偷拍欧美日韩| 欧美人妻视频在线| 7799综合| 男女拍拍| 91人妻人人澡人人添人人爽| 精品A片| 丁香视频在线观看| 日韩午夜AV| 中文无码日本高潮喷水| 婷婷五月天色色| 日本高清视频九区| 蜜臀久久久99久久久久久久| 国产午夜福利视频| 欧美性生交18XXXXX无码| 在线成人| 少妇人妻一区二区三区| 亚洲一级在线观看| 日韩第三页| 一区二区三区高清| 色婷婷Av一区| 亚洲精品成a人在线观看| 大香蕉伊人成人网| 天天插一插| 奇米超碰| 99久在线精品99re8| 激情一级片| 亚洲日本黄色视频| 婷婷丁香人妻天天爽| 超碰人人在线观看| 综合成人在线| 日逼中文字幕| 久久久久久久久久久久久久久久久久免费精品分类视频 | 详情:绿帽夫妻多人运动开淫啪-91n | 成全在线观看高清的| 成人免费福利| 国产真实乱婬A片三区高清蜜臀| 大香蕉伊人免费| www.男人天堂| 亚洲精品国产精品乱码不卡√香蕉 | 成人AV一区二区三区| 大香蕉国产精品| 亚洲无码视频在线免费观看| 欧美日韩国产一区二区三区| 国产精品偷拍视频| 精品一区二区三区四区视频| 国产欧美综合在线观看| 操一操影院| 老女人肏屄视频| 亚洲性爱视频在线观看| 艹逼91| 欧美日韩在线免费观看| 不卡无码高清| 欧美一区三区视频z| 99精品视频免费看| 国产精品免费人成网站酒店| 黄色一级免费| 制服丝袜在线视频| 狠狠的操| 国产亚洲久一区二区三区| 亚洲福利视频网| www.蜜桃av| 国产天堂在线| 在线观看www视频| 国产十欧洲十美国+亚洲一二三区在线午夜 | 成人午夜精品福利免费| а√最新版在线中文8| 亚洲天堂AV2025| 久久一级视频| 亚洲AV无码乱码国产精品黑人 | 亚洲无吗在线播放| 国产porn| 日本免费色视频| 成人国产精品秘在线看| 黄色A片一级| 国产思思99re99在线观看| 黄色福利网站| 插逼视频网站| 成人综合大香蕉| 99激情| 亚洲中文字幕在线视频观看 | 亚洲香蕉视频| 激情五月在线| 91人妻人人澡人人爽人人DVD | 欧美熟妇性爱视频| 国产一级a爱做片免费☆观看| 秋霞福利影院| 国产91探花系列在线观看| 97人妻一区二区三区| 超碰欧美在线| 欧美一区二区丁香五月天激情| 天天操天天干天天射| 国产久久久久久久久久| 黄色av无码| 成人免费网站| 大香蕉免费在线观看| 天天日夜| 久久国产无码| 亚洲国产无码在线| 最近中文字幕在线观看| 三级片日本在线| 亚洲AV高清无码| 免费在线观看亚洲| 懂色av粉嫩AV蜜臀AV| 麻豆免费成人视频| 中文字幕第11页| 大黑逼AV| 五月丁香在线视频| 香蕉视频亚洲| 美女91网站色| AA片免费| 久久久天堂国产精品女人| 免费内射视频| 大香蕉大香蕉网| 911国产视频| 久久久久久久久久国产精品免费观看-百度 | 91福利网站| 爱射网| 99re视频播放| 第一色影院| 欧美另类色| 可以看的毛片| 色狠狠AV| 国产一级内射| 日韩高清一级| 2026国产精品视频| 日爽夜爽| 国产女人18毛片水18精品软件| 大香蕉欧美| 精品91海角乱| 97精品人人妻人人| 国产又粗又猛又爽又黄91精品| 日韩三级片网址| 国产一区二区00000视频| 神马午夜51| 熟妇人妻中文AV无码| 无码区一区二区| 日本三区视频| 起碰在线视频| 大秀91视频| 国产精品免费人成人网站酒店| 国产精品毛片一区二区在线看| 激情乱伦网| yw在线观看| 亚洲成人视屏| 插菊花综合网站| 起碰在线视频| 正在播放亚洲| 免费看成人747474九号视频在线观看| 国产黄色视频在线免费观看| 国产办公室丝袜人妖| 人人干视频| 91豆花在线| 国内精品人妻无码久久久影院蜜桃| 欧美综合亚洲图片综合区| 色接久久| 操B在线观看| 欧美色图另类| 黄色视频小说| 美日韩一区二区三区| 91九色蝌蚪91POR成人| 狠狠色av| 亚洲超级高清无码第一在线视频观看 | 日韩肏屄视频在线观看| 日韩视频一区| 99精品久久| 久久亚洲AV| 日韩欧美高清第一期| 国产无套免费网站69| 久久久久久久免费| 日本AA片视频| 五月大香蕉| 在线免费中文字幕| 手机看片1024你懂的| 91精品91久久久中77777| 无码精品人妻一区二区欧美| 免费无码A片在线观看全| 开心四房播播第四婷婷| 日韩毛片在线| 日韩视频在线免费观看| 18禁在线| h片在线| 91麻豆国产| 亚洲AV成人片无码网站网蜜柚| 中文字幕第98页| 国产精品成人无码| 亚洲欧美国产日韩字幕| 狠狠操狠狠操狠狠操| 亚洲成人娱乐网| 一道本一区二区三区| 国产精品国产精品| av天天看| 欧美黄色性爱| 污视频网站在线观看| 亚洲AV无码成人专区| 欧美精产国品一二三区别| 日中文字幕| 国产精品99视频| 不卡的一区二区| 牛牛精品一区二区| 91jiujiu|