<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          6 種在 React 中獲取數(shù)據(jù)的方法

          共 8237字,需瀏覽 17分鐘

           ·

          2023-08-16 17:26

          原文 | https://medium.com/@Choco23/6-ways-to-get-data-in-react-528dd11f267

          數(shù)據(jù)獲取是任何 react 應(yīng)用程序的核心方面。對(duì)于 React 開發(fā)人員來說,了解不同的數(shù)據(jù)獲取方法以及哪些用例最適合他們很重要。

          但首先,讓我們了解 JavaScript Promises

          簡而言之,promise 是一個(gè) JavaScript 對(duì)象,它將在未來的某個(gè)時(shí)間產(chǎn)生一個(gè)值。這通常適用于異步操作(例如數(shù)據(jù)獲取)。
          Promises具有三種狀態(tài):
          • Pending:承諾仍在進(jìn)行中的地方
          • Fulfilled:承諾成功解決并返回值的地方
          • Rejected:承諾因錯(cuò)誤而失敗
          如果一個(gè)promise被Fulfilled或Rejected,它就被解決了。Promise 有不同的方法來根據(jù)結(jié)果做不同的事情。下一節(jié)將更詳細(xì)地討論這些方法。

          1、使用 Promise 方法獲取 api

          Fetch API 提供了一個(gè)全局的 fetch() 方法,使開發(fā)人員能夠以直接的方式獲取數(shù)據(jù)。在 fetch() 之前,傳統(tǒng)方法是使用 XMLHttpRequest()。(本文不涉及此方法,因?yàn)?fetch() 已被更強(qiáng)大、更靈活的功能集所取代。)
          fetch() 方法接受一個(gè)參數(shù),即要請求的 URL,并返回一個(gè)promise。第二個(gè)可選參數(shù)options 是一個(gè)屬性數(shù)組。fetch() 的返回值可以是 JSON 或 XML(對(duì)象數(shù)組或單個(gè)對(duì)象)。如果沒有選項(xiàng)參數(shù),fetch() 將始終發(fā)出 GET 請求。
          第一種方法是您通常會(huì)在簡單的數(shù)據(jù)獲取用例中看到的方法,并且通常是瀏覽 API 文檔時(shí)的第一個(gè)結(jié)果。
          如前所述,我們從返回狗的隨機(jī)圖像的 API 獲取數(shù)據(jù),并將該圖像呈現(xiàn)在屏幕上。在發(fā)出請求之前,我們將代碼包裝在一個(gè)帶有空依賴項(xiàng)數(shù)組的 useEffecthook 中,以便 fetch() 方法僅在組件最初安裝時(shí)運(yùn)行。
             
          useEffect(() => {    fetch(URL)      // syntax for handling promises      .then((res) => {        // check to see if response is okay        if (res.ok) {          // if okay, take JSON and parse to JavaScript object          return res.json();        }        throw res;      })      //  .json() returns a promise as well      .then((data) => {        console.log(data);        // setting response as the data state        setData(data);      })      // if res is not okay the res is thrown here for error      .catch((err) => {        console.error(`Error: ${err}`);        // setting the error state        setError(err);      })      //  regardless if promise resolves successfully or not we remove loading state      .finally(() => {        setLoading ( false );      });  }, []);

          在上例中,我們調(diào)用該方法并傳入 API 端點(diǎn)的 URL。在這個(gè)方法中,我們使用 promise 對(duì)象的方法(回想一下返回一個(gè) promise)。

          我們使用這個(gè)方法并傳入一個(gè)回調(diào)函數(shù)來檢查響應(yīng)是否正常。如果響應(yīng)正常,我們將獲取返回的 JSON 數(shù)據(jù)并使用該方法將其解析為 JavaScript 對(duì)象。如果響應(yīng)不正常,我們就會(huì)報(bào)錯(cuò)。

          由于 .json() 方法也返回一個(gè)承諾,我們可以鏈接另一個(gè) .then() 并傳遞一個(gè)函數(shù)來設(shè)置數(shù)據(jù)的狀態(tài),然后在組件的其他地方使用。在我們的示例中,外部 API 返回一個(gè)具有 url 屬性的對(duì)象(它將用作 srcour 圖像)。

          繼續(xù)通過鏈,下一部分是 .catch() 以安排在承諾被拒絕時(shí)調(diào)用的函數(shù)。這也返回另一個(gè)承諾,然后我們可以鏈接 .finally() 無論承諾是否已解決(解決或拒絕),它都會(huì)被調(diào)用。

          這種 .finally() 方法使我們能夠避免在 .then() 和 .catch() 中重復(fù)代碼,使其成為我們示例中刪除加載狀態(tài)的好地方。

          2、帶有 Promise 方法的庫 Axios

          Axios 是一個(gè)流行的 HTTP 客戶端庫,用于高效的數(shù)據(jù)獲取。它可以通過 npm 或其他包管理器輕松安裝到 React 應(yīng)用程序中。使用 Axios 是 Fetch API 的替代方法,如果您不介意安裝外部庫,它有一些優(yōu)勢。

          第二個(gè)示例將非常接近第一個(gè)示例的代碼,使用相同的 promise 方法來處理 promise 狀態(tài)和響應(yīng)。

          在 fetch() 將 Axios 庫導(dǎo)入我們的組件之后,我們可以使用 axios.get() 一種可以將 URL 傳遞到我們的外部 API 端點(diǎn)的方法。

          這將返回一個(gè) Promise,因此我們可以采用與 Promise 方法鏈接相同的方法。

             
          useEffect(() => {    axios.get(URL)      // syntax for handling promises      .then((res) => {        console.log(res.data);        // axios converts json to object for us (shortens our code)        setData(res.data);      })      // axios takes care of error handling for us instead of checking manually      .catch((err) => {        console.error(`Error: ${err}`);        // setting the error state        setError(err);      })      //  regardless if promise resolves successfully or not we remove loading state      .finally(() => {        setLoading ( false );      });  }, []);

          Fetch API 的代碼與此 Axios 方法之間的明顯區(qū)別在于,使用 Axios 我們只需要一個(gè),因?yàn)?Axios 為我們將 .then()JSON 轉(zhuǎn)換為 JavaScript 對(duì)象(縮短了我們的代碼)。

          另外,我們不再寫條件來手動(dòng)拋出錯(cuò)誤,因?yàn)閍xios會(huì)為你拋出400和500范圍的錯(cuò)誤(再次縮短我們的代碼)。

          3 、異步函數(shù)(async/await)

          在此示例中,我們將放棄在前兩個(gè)示例中使用的承諾鏈,而是引入一種更現(xiàn)代的方法來編寫異步的、基于承諾的代碼。

          這種方法可以與您選擇的任何抓取機(jī)制一起使用,但對(duì)于本示例,我們將堅(jiān)持使用 Axios 庫。

          第三個(gè)示例與前一個(gè)示例類似的方式設(shè)置組件,方法是導(dǎo)入 Axios 庫,然后使用一個(gè)空的 dependencies 數(shù)組包裝用于在 useEffecta 中獲取數(shù)據(jù)的代碼。

          在 useEffect 中,我們使用關(guān)鍵字 async 創(chuàng)建一個(gè)異步函數(shù),然后在該函數(shù)中我們有三個(gè)獨(dú)立的部分 - try、catch 和 finally。

          這種 try/catch 方法用于處理 JavaScript 中的錯(cuò)誤。try塊內(nèi)的代碼首先被執(zhí)行,如果拋出任何錯(cuò)誤,它們將被“捕獲”在塊中,catch并執(zhí)行內(nèi)部代碼。

          最后,finallyblock 將始終在流通過 try/catch 之后執(zhí)行。

             
          useEffect(() => {    // create async function b/c cannot use async in useEffect arg cb    const fetchData = async () => {    //   with async/await use the try catch block syntax for handling      try {        // using await to make async code look sync and shorten         const res = await axios.get(URL);        setData(res.data);      } catch (err) {        console.error(`Error: ${err}`);        // setting the error state        setError(err);      } finally {        setLoading ( false );      }    };
          fetchData (); }, []);

          在此示例中,try 塊創(chuàng)建了一個(gè)名為 res(response 的縮寫)的變量,該變量使用 async 關(guān)鍵字。這允許代碼看起來同步(更短,更容易在眼睛上)。

          在此示例中,axios.get(URL) 正在“等待”直到它穩(wěn)定下來。如果承諾得到履行,那么我們將數(shù)據(jù)設(shè)置為狀態(tài)。如果承諾被拒絕(拋出錯(cuò)誤),它會(huì)進(jìn)入 catch 塊。

          4、 創(chuàng)建一個(gè)“useFetch”自定義 React Hook

          第四種方法是創(chuàng)建我們自己的自定義 React 鉤子,調(diào)用 useFetchit 可以在我們應(yīng)用程序的不同組件中重復(fù)使用,并從每個(gè)組件中刪除笨重的獲取代碼。

          這個(gè)例子實(shí)際上只是采用第四個(gè)例子(使用 Axios 庫和 async/await 的相同技術(shù))并將該代碼移動(dòng)到它自己的自定義鉤子中。

          為此,我們創(chuàng)建了一個(gè)名為 useFetch.js 的函數(shù)。然后我們使用 Effect 將前面示例中的所有代碼以及我們正在跟蹤的不同狀態(tài)添加到函數(shù) useFetch 中。

          最后,這個(gè)函數(shù)將返回一個(gè)包含每個(gè)狀態(tài)的對(duì)象,然后在調(diào)用鉤子的地方使用 useFetchaccessed。我們的 useFetchhook 還將接受一個(gè)參數(shù),即 URL ,以允許更多的可重用性和向不同端點(diǎn)發(fā)出提取請求的可能性。

             
          const useFetch = (url) => {  const [data, setData] = useState(null);  const [ loading , setLoading ] =  useState ( true );  const [error, setError] = useState(null);
          useEffect(() => { // create async function b/c cannot use asyc in useEffect arg cb const fetchData = async () => { // with async/await use the try catch block syntax for handling try { // using await to make async code look sync and shorten const res = await axios.get(url); setData(res.data); } catch (err) { console.error(`Error: ${err}`); // setting the error state setError(err); } finally { setLoading ( false ); } };
          fetchData (); }, []);
          return { data, loading, error, };};

          最后,我們將這個(gè)新的自定義鉤子導(dǎo)入到將使用它的組件中,并像調(diào)用任何其他 React 鉤子一樣調(diào)用它。如您所見,這極大地提高了代碼的可讀性并縮短了我們的組件。

          這種方法的最后一點(diǎn)是您還可以安裝外部庫而不是創(chuàng)建您自己的自定義掛鉤。一個(gè)流行的庫 react-fetch-hook 與我們剛剛構(gòu)建的鉤子具有非常相似的功能。

          5、 React 查詢庫

          在 React 中獲取數(shù)據(jù)的最現(xiàn)代和最強(qiáng)大的方法之一是使用 React Query 庫。除了簡單的數(shù)據(jù)獲取之外,它還有許多功能,但是對(duì)于這個(gè)例子,我們將學(xué)習(xí)如何從同一個(gè)示例外部 API 中簡單地獲取數(shù)據(jù)。

          安裝和導(dǎo)入后,React Query 提供了許多自定義掛鉤,可以以非常干凈的方式在我們的組件中重復(fù)使用。

          在此示例中,我們從中導(dǎo)入 QueryClient,然后使用提供程序包裝我們的應(yīng)用程序,并將 QueryClientProvider 實(shí)例作為屬性傳遞給包裝器。

          這使我們能夠在我們的應(yīng)用程序中使用該庫。

          為了發(fā)出這個(gè)簡單的 GET 請求,我們導(dǎo)入并使用了 useQueryhooks。與前面使用自定義掛鉤的示例不同,我們傳入了兩個(gè)參數(shù)。

          第一個(gè)必需參數(shù)是 queryKey ,用作此特定查詢的參考鍵。

          第二個(gè)必需參數(shù)是 queryFn ,它是查詢將用于請求數(shù)據(jù)的函數(shù)。

          我們將使用此查詢函數(shù),然后使用 Fetch API 和 promise 方法語法進(jìn)行初始提取,而不是像我們之前的自定義掛鉤示例中那樣只傳遞一個(gè)簡單的 URL。(這個(gè)鉤子有許多其他可選參數(shù)。)

             
          const { isLoading, error, data } = useQuery("dogData", () => fetch(URL).then((res) => res.json()));

          isLoading 從這里開始,React Query 將在幕后完成所有額外的工作,在這種情況下,我們可以從這個(gè)鉤子調(diào)用 destructure 、 error 和 use data in our application,盡管我們也可以訪問許多其他值。

          在比我們當(dāng)前的 Dog Image API 示例更大的示例中,使用 React Query 的力量和優(yōu)勢是顯而易見的。需要提及的一些附加功能包括:緩存、在后臺(tái)更新“陳舊”數(shù)據(jù)以及其他與性能相關(guān)的優(yōu)勢。

          6、 Redux 工具包 RTK 查詢

          本文最后一種方法是使用Redux Toolkit的RTK Query進(jìn)行數(shù)據(jù)采集。應(yīng)用程序使用 Redux 進(jìn)行狀態(tài)管理是很常見的。

          如果您的公司或您當(dāng)前的副項(xiàng)目目前正在使用 Redux,一個(gè)不錯(cuò)的選擇是使用 RTK 查詢來獲取數(shù)據(jù),因?yàn)樗峁┝伺c React 查詢類似的簡單性和優(yōu)勢。

          要在存儲(chǔ) Redux 代碼的任何地方開始使用 RTK 查詢,請創(chuàng)建一個(gè) rtkQueryService.js 文件來設(shè)置數(shù)據(jù)獲取。

          創(chuàng)建后,您將服務(wù)添加到您的 Redux 商店,假設(shè)您已經(jīng)在使用 Redux,您將已經(jīng)擁有一個(gè)包含您的應(yīng)用程序的 <Provider>store 組件。

          從這里開始,它與使用帶有 React Query 方法的自定義鉤子非常相似,您導(dǎo)入然后使用查詢鉤子并解構(gòu)數(shù)據(jù),錯(cuò)誤然后是 Loading 可以在您的組件中使用。

              
          const { data, error, isLoading } = useGetDogQuery();

          如您所見,Redux 有很多設(shè)置,因此這可能不是我們用例的最佳方法,但如果您已經(jīng)在 React 應(yīng)用程序中使用 Redux 并且想要一種簡單而現(xiàn)代的獲取數(shù)據(jù)的方式,RTK 查詢 可能很棒很有價(jià)值,這也提供了緩存等好處。

          最后的想法

          如果你已經(jīng)看到了這里,那么恭喜你!這篇文章的目的就是為那些學(xué)習(xí) React 的人介紹一些不同的數(shù)據(jù)獲取方法。

          在這篇文章中,我介紹了6種方法,希望這6種方法對(duì)你有用,也希望你能從中學(xué)習(xí)到一些新東西。

          此外,還有其他當(dāng)前的數(shù)據(jù)獲取方法未在此文章中提及,我相信隨著 React 生態(tài)系統(tǒng)的發(fā)展,其他方法將會(huì)出現(xiàn)。也就是說,我相信本文為理解該領(lǐng)域提供了堅(jiān)實(shí)的基礎(chǔ)。


          學(xué)習(xí)更多技能

          請點(diǎn)擊下方公眾號(hào)


          瀏覽 504
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚州中文无码字母 | 人妻精品无码 | 国产骚逼网站 | 天天躁日日躁狠狠躁欧美男男 | 黄色一级片在线免费观看 |