首頁 > web前端 > js教程 > 主體

react中請求遠端資料的四種方法是什麼

青灯夜游
發布: 2021-11-30 10:30:57
原創
2651 人瀏覽過

請求遠端資料的四種方法:1、直接在React元件中進行HTTP呼叫並處理回應;2、建立一個資料夾,把進行HTTP呼叫的函數都放進去,集中請求資料並處理回應;3、自訂Hook來請求資料;4、使用「react-query」或swr來請求資料。

react中請求遠端資料的四種方法是什麼

本教學操作環境:Windows7系統、react17.0.1版、Dell G3電腦。

React 中請求遠端資料的四種方法

React 是一個專注的元件庫。因此,它對如何請求遠端資料沒有什麼建議。如果要透過 HTTP 請求資料並將其傳送到 Web API,可以考慮以下四種方法。

  • 內聯寫入法

  • 集中管理

  • 自訂Hook

  • react-query/swr

#注意:在本文中,我將使用fetch 進行HTTP 調用,但這些模式也適用於Axios 之類的替代方法。另外,如果你使用的是 GraphQ L,也可以考慮其他使用 Apollo 之類的不錯的選擇。這篇文章假設你正在呼叫傳統的 REST API。

方式1:內嵌

這是最簡單,最直接的選擇。在 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 只運行一次

#這只是一個簡單的範例,它忽略了許多其他相關問題。

方式2:資料夾集中管理

如果我們在一個資料夾中處理所有HTTP 呼叫會怎麼樣? 使用這個方法,我們創建了一個名為services 的資料夾,並且把進行HTTP 呼叫的函數都放進去。 service 是最受歡迎的術語,我在下面也討論了很多好的替代名稱,例如 clientapi

react中請求遠端資料的四種方法是什麼

重點是,所有的 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 呼叫的函數,那麼我可以輕鬆地確保它們始終如一地這樣做。此外,如果呼叫被重複使用,則很容易從這個集中位置呼叫它們。

然而,我們還可以做得更好。

方式3:自訂Hook

借助 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:

方式4:react-query/swr

使用 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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板