請求遠端資料的四種方法:1、直接在React元件中進行HTTP呼叫並處理回應;2、建立一個資料夾,把進行HTTP呼叫的函數都放進去,集中請求資料並處理回應;3、自訂Hook來請求資料;4、使用「react-query」或swr來請求資料。
本教學操作環境:Windows7系統、react17.0.1版、Dell G3電腦。
React
是一個專注的元件庫。因此,它對如何請求遠端資料沒有什麼建議。如果要透過 HTTP
請求資料並將其傳送到 Web API
,可以考慮以下四種方法。
內聯寫入法
集中管理
自訂Hook
react-query/swr
#注意:在本文中,我將使用fetch 進行HTTP 調用,但這些模式也適用於Axios 之類的替代方法。另外,如果你使用的是 GraphQ L,也可以考慮其他使用 Apollo 之類的不錯的選擇。這篇文章假設你正在呼叫傳統的 REST API。
這是最簡單,最直接的選擇。在 React
元件中進行 HTTP
呼叫並處理回應。
fetch("/users").then(response => response.json());
看起來很簡單。但是這個範例忽略了載入狀態,錯誤處理,聲明和設定相關狀態等。在現實世界中, HTTP
呼叫看起來更像這樣。
import React, { useState, useEffect } from "react"; export default function InlineDemo() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch(`${process.env.REACT_APP_API_BASE_URL}users`) .then(response => { if (response.ok) return response.json(); throw response; }) .then(json => { setUsers(json); }) .catch(err => { console.error(err); setError(err); }) .finally(() => { setLoading(false); }); }, []); if (loading) return "Loading..."; if (error) return "Oops!"; return users[0].username; }
對於一個簡單的應用程序,只要發起幾個請求,就可以正常工作。但是上面的狀態宣告和 useEffect
都是模版。如果我要進行許多 HTTP
調用,我不想為每個調用重複和維護大約 20 行程式碼。內聯呼叫讓你的程式碼變得很醜。
看一下我們要解決的一些問題:
宣告載入狀態
宣告錯誤狀態
#將錯誤印到控制台
檢查回應是否透過傳回200 response.ok
如果回應正常,將回應轉換為json
並傳回promise
#如果回應不正確,拋出錯誤
在finally
中隱藏載入狀態,以確保Loading
即使發生錯誤也被隱藏
聲明一個空的依賴項數組,以便useEffect
只運行一次
#這只是一個簡單的範例,它忽略了許多其他相關問題。
如果我們在一個資料夾中處理所有HTTP
呼叫會怎麼樣? 使用這個方法,我們創建了一個名為services
的資料夾,並且把進行HTTP 呼叫的函數都放進去。 service
是最受歡迎的術語,我在下面也討論了很多好的替代名稱,例如 client
或 api
。
重點是,所有的 HTTP
呼叫都是透過純 JavaScript
函數處理的,儲存在一個資料夾中。這是一個集中的getUsers
函數:
export function getUsers() { return fetch(`${process.env.REACT_APP_API_BASE_URL}users`).then(response => response.json() ); }
下面是對getUsers
函數的呼叫:
import React, { useState, useEffect } from "react"; import { getUsers } from "./services/userService"; export default function CentralDemo() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { getUsers() .then(json => { setUsers(json); setLoading(false); }) .catch(err => { console.error(err); setError(err); }); }, []); if (loading) return "Loading..."; if (error) return "Oops!"; return users[0].username; }
然而這並沒有太簡化請求呼叫。主要的好處是它可以強制一致地處理 HTTP
呼叫。其想法是這樣的:當相關函數一起處理時,更容易一致地處理它們。如果 userService
資料夾中充滿了進行 HTTP
呼叫的函數,那麼我可以輕鬆地確保它們始終如一地這樣做。此外,如果呼叫被重複使用,則很容易從這個集中位置呼叫它們。
然而,我們還可以做得更好。
借助 React Hooks
的魔力,我們終於可以集中處理重複的邏輯。那麼如何建立一個自訂 useFetch
鉤子來簡化我們的 HTTP
呼叫呢?
import { useState, useEffect, useRef } from "react"; // This custom hook centralizes and streamlines handling of HTTP calls export default function useFetch(url, init) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const prevInit = useRef(); const prevUrl = useRef(); useEffect(() => { // Only refetch if url or init params change. if (prevUrl.current === url && prevInit.current === init) return; prevUrl.current = url; prevInit.current = init; fetch(process.env.REACT_APP_API_BASE_URL + url, init) .then(response => { if (response.ok) return response.json(); setError(response); }) .then(data => setData(data)) .catch(err => { console.error(err); setError(err); }) .finally(() => setLoading(false)); }, [init, url]); return { data, loading, error }; }
你的可能看起來不一樣,但我發現這個基本的使用方法很有用。這個 Hook 極大地簡化了所有呼叫。看看使用這個 Hook
需要多少代碼 :
import React from "react"; import useFetch from "./useFetch"; export default function HookDemo() { const { data, loading, error } = useFetch("users"); if (loading) return "Loading..."; if (error) return "Oops!"; return data[0].username; }
對於許多應用程序,你只需要一個這樣的自訂Hook。但是這個Hook已經很複雜了,而且它消除了許多問題。
但是還有很多我們沒有考慮到的點:快取? 、如果客戶端的連線不可靠,如何重新取得?你想在用戶重新調整標籤時重新取得新數據嗎?如何消除重複查詢?
你可以不斷完善這個自訂Hook來完成所有這些操作。但是,您應該只需要方式4:
使用 react-query或swr
,可以为我们处理缓存、重试、重复查询等等。我不必维护自己的自定义Hook了。而且每个 HTTP
调用都需要很少的代码:
import React from "react"; import { getUsers } from "./services/userService"; import { useQuery } from "react-query"; export default function ReactQueryDemo() { const { data, isLoading, error } = useQuery("users", getUsers); if (isLoading) return "Loading..."; if (error) return "Oops!"; return data[0].username; }
对于大多数应用程序来说,今天这是我的首选。这是完整的代码:https://codesandbox.io/s/4-ways-to-handle-restful-http-in-react-k3xug
,你可以自己进行比较。
推荐学习:《react视频教程》
以上是react中請求遠端資料的四種方法是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!