Empat cara untuk meminta data jauh: 1. Buat panggilan HTTP terus dalam komponen React dan proses respons 2. Buat folder, letakkan semua fungsi yang membuat panggilan HTTP ke dalamnya, dan minta data secara berpusat dan memprosesnya Respons; 3. Sesuaikan Hook untuk meminta data; 4. Gunakan "react-query" atau swr untuk meminta data.
Persekitaran pengendalian tutorial ini: sistem Windows 7, bertindak balas versi 17.0.1, komputer Dell G3.
React
ialah perpustakaan komponen khusus. Oleh itu, ia mempunyai sedikit cadangan tentang cara meminta data jauh. Jika anda ingin meminta data melalui HTTP
dan menghantarnya ke Web API
, berikut ialah empat pendekatan untuk dipertimbangkan.
Tulisan sebaris
Pengurusan berpusat
TersuaiHook
react-query/swr
Nota: Dalam artikel ini saya akan menggunakan fetch untuk membuat panggilan HTTP, tetapi corak ini digunakan pada Axios juga alternatif seperti itu. Sebagai alternatif, jika anda menggunakan GraphQ L, terdapat pilihan lain yang bagus untuk dipertimbangkan seperti Apollo. Artikel ini menganggap anda sedang memanggil API REST tradisional.
Ini adalah pilihan yang paling mudah dan paling mudah. Buat panggilan React
dalam komponen HTTP
dan kendalikan respons.
fetch("/users").then(response => response.json());
Nampak ringkas. Tetapi contoh ini mengabaikan status pemuatan, pengendalian ralat, pengisytiharan dan penetapan status berkaitan, dsb. Di dunia nyata, panggilan HTTP
akan kelihatan lebih seperti ini.
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; }
Untuk aplikasi mudah, cuma buat beberapa permintaan dan ia akan berfungsi dengan baik. Tetapi pengisytiharan status dan useEffect
di atas adalah kedua-dua templat. Jika saya akan membuat banyak HTTP
panggilan, saya tidak mahu mengulang dan mengekalkan kira-kira 20 baris kod untuk setiap panggilan. Panggilan dalam talian menjadikan kod anda kelihatan hodoh.
Lihat beberapa isu yang kami cuba selesaikan:
Mengisytiharkan status pemuatan
Mengisytiharkan status ralat
Cetak ralat ke konsol
Periksa sama ada respons diluluskan pulangkan 200 response.ok
Jika respons OK, Tukar respons kepada json
dan kembalikan promise
Jika respons tidak betul, ralat buang
tersembunyi dalam finally
Keadaan memuatkan, untuk memastikan Loading
disembunyikan walaupun ralat berlaku
Isytihar tatasusunan dependensi kosong supaya useEffect
hanya berjalan sekali
Ini hanyalah contoh mudah yang mengabaikan banyak isu lain yang berkaitan.
Bagaimana jika kami mengendalikan semua HTTP
panggilan dalam satu folder Menggunakan kaedah ini, kami mencipta fail bernama folder services
dan meletakkan semua fungsi yang membuat panggilan HTTP ke dalamnya. service
ialah istilah yang paling popular dan saya juga telah membincangkan banyak nama alternatif yang baik di bawah seperti client
atau api
.
Perkara utama ialah semua HTTP
panggilan dikendalikan melalui fungsi JavaScript
tulen, disimpan dalam folder. Ini ialah fungsi getUsers
berpusat:
export function getUsers() { return fetch(`${process.env.REACT_APP_API_BASE_URL}users`).then(response => response.json() ); }
Berikut ialah panggilan ke fungsi 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; }
Walau bagaimanapun ini tidak terlalu memudahkan panggilan permintaan. Faedah utama ialah ia menguatkuasakan pengendalian yang konsisten bagi HTTP
panggilan. Ideanya ialah: apabila fungsi berkaitan diproses bersama, lebih mudah untuk memprosesnya secara konsisten. Jika folder userService
penuh dengan fungsi membuat HTTP
panggilan, saya boleh memastikan mereka melakukannya secara konsisten dengan mudah. Selain itu, jika panggilan digunakan semula, ia mudah digunakan dari lokasi berpusat ini.
Walau bagaimanapun, kami boleh melakukan yang lebih baik.
Dengan keajaiban React Hooks
, akhirnya kita boleh menumpukan pada memproses logik berulang. Jadi, bagaimanakah kita boleh membuat cangkuk useFetch
tersuai untuk memudahkan panggilan HTTP
kami?
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 }; }
Pilihan anda mungkin kelihatan berbeza, tetapi saya dapati penggunaan asas ini membantu. Cangkuk ini sangat memudahkan semua panggilan. Lihat berapa banyak kod yang diperlukan untuk menggunakan ini 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; }
Untuk banyak aplikasi, anda hanya memerlukan Cangkuk tersuai seperti ini. Tetapi Hook ini sudah kompleks, dan ia menghapuskan banyak masalah.
Tetapi masih terdapat banyak perkara yang belum kami pertimbangkan: caching? . Jika sambungan pelanggan tidak boleh dipercayai, bagaimana untuk mendapatkannya semula? Adakah anda mahu mengambil semula data baharu apabila pengguna mengubah saiz label? Bagaimana untuk menghapuskan pertanyaan pendua?
Anda boleh terus menambah baik Hook tersuai ini untuk melengkapkan semua operasi ini. Walau bagaimanapun, anda hanya perlu cara 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视频教程》
Atas ialah kandungan terperinci Apakah empat kaedah untuk meminta data jauh sebagai tindak balas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!