Pengambilan Data basi sambil memvalidasi ulang dengan React Hooks: Panduan
Diterbitkan: 2022-03-11Memanfaatkan ekstensi HTTP Cache-Control
basi-sementara-validasi ulang adalah teknik yang populer. Ini melibatkan penggunaan aset yang di-cache (basi) jika ditemukan dalam cache, dan kemudian memvalidasi ulang cache dan memperbaruinya dengan versi aset yang lebih baru jika diperlukan. Karenanya nama stale-while-revalidate
.
Bagaimana stale-while-revalidate
Bekerja
Saat permintaan dikirim untuk pertama kalinya, permintaan akan di-cache oleh browser. Kemudian, ketika permintaan yang sama dikirim untuk kedua kalinya, cache diperiksa terlebih dahulu. Jika cache permintaan itu tersedia dan valid, cache dikembalikan sebagai respons. Kemudian, cache diperiksa untuk basi dan diperbarui jika ditemukan basi. Kedaluwarsa cache ditentukan oleh nilai max-age
ada di header Cache-Control
bersama dengan stale-while-revalidate
.
Ini memungkinkan pemuatan halaman yang cepat, karena aset yang di-cache tidak lagi berada di jalur kritis. Mereka dimuat secara instan. Selain itu, karena pengembang mengontrol seberapa sering cache digunakan dan diperbarui, mereka dapat mencegah browser menampilkan data yang terlalu usang kepada pengguna.
Pembaca mungkin berpikir bahwa, jika mereka dapat meminta server menggunakan header tertentu dalam responsnya dan membiarkan browser mengambilnya dari sana, lalu apa perlunya menggunakan React dan Hooks untuk caching?
Ternyata pendekatan server-and-browser hanya berfungsi dengan baik ketika kita ingin men-cache konten statis. Bagaimana dengan menggunakan stale-while-revalidate
untuk API dinamis? Sulit untuk menemukan nilai yang baik untuk max-age
dan stale-while-revalidate
dalam kasus itu. Seringkali, membatalkan cache dan mengambil respons baru setiap kali permintaan dikirim akan menjadi pilihan terbaik. Ini secara efektif berarti tidak ada caching sama sekali. Tapi dengan React dan Hooks, kita bisa melakukan yang lebih baik.
stale-while-revalidate
untuk API
Kami melihat bahwa validasi stale-while-revalidate
HTTP tidak berfungsi dengan baik dengan permintaan dinamis seperti panggilan API.
Bahkan jika kita akhirnya menggunakannya, browser akan mengembalikan cache atau respons baru, bukan keduanya. Ini tidak cocok dengan permintaan API karena kami ingin tanggapan baru setiap kali permintaan dikirim. Namun, menunggu tanggapan baru menunda kegunaan aplikasi yang berarti.
Jadi apa yang kita lakukan?
Kami menerapkan mekanisme caching khusus. Di dalamnya, kami mencari cara untuk mengembalikan cache dan respons baru. Di UI, respons yang di-cache diganti dengan respons baru saat tersedia. Beginilah logikanya akan terlihat:
- Saat permintaan dikirim ke titik akhir server API untuk pertama kalinya, simpan respons di cache, lalu kembalikan.
- Saat berikutnya permintaan API yang sama terjadi, segera gunakan respons yang di-cache.
- Kemudian, kirim permintaan secara asinkron untuk mengambil respons baru. Saat respons tiba, sebarkan perubahan ke UI secara asinkron dan perbarui cache.
Pendekatan ini memungkinkan pembaruan UI seketika—karena setiap permintaan API di-cache—tetapi juga kebenaran akhirnya di UI karena data respons baru ditampilkan segera setelah tersedia.
Dalam tutorial ini, kita akan melihat pendekatan langkah demi langkah tentang cara mengimplementasikannya. Kami akan menyebut pendekatan ini basi-saat-refresh karena UI sebenarnya di- refresh ketika mendapat respons baru.
Persiapan: API
Untuk memulai tutorial ini, pertama-tama kita membutuhkan API tempat kita mengambil data. Untungnya, ada banyak layanan API tiruan yang tersedia. Untuk tutorial ini, kita akan menggunakan reqres.in.
Data yang kami ambil adalah daftar pengguna dengan parameter kueri page
. Beginilah tampilan kode pengambilannya:
fetch("https://reqres.in/api/users?page=2") .then(res => res.json()) .then(json => { console.log(json); });
Menjalankan kode ini memberi kita output berikut. Ini adalah versi yang tidak berulang:
{ page: 2, per_page: 6, total: 12, total_pages: 2, data: [ { id: 7, email: "[email protected]", first_name: "Michael", last_name: "Lawson", avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/follettkyle/128.jpg" }, // 5 more items ] }
Anda dapat melihat bahwa ini seperti API nyata. Kami memiliki pagination dalam respons. Parameter kueri page
bertanggung jawab untuk mengubah halaman, dan kami memiliki total dua halaman dalam kumpulan data.
Menggunakan API di Aplikasi React
Mari kita lihat bagaimana kita menggunakan API di dalam Aplikasi React. Setelah kita tahu bagaimana melakukannya, kita akan mengetahui bagian caching. Kami akan menggunakan kelas untuk membuat komponen kami. Berikut kodenya:
import React from "react"; import PropTypes from "prop-types"; export default class Component extends React.Component { state = { users: [] }; componentDidMount() { this.load(); } load() { fetch(`https://reqres.in/api/users?page=${this.props.page}`) .then(res => res.json()) .then(json => { this.setState({ users: json.data }); }); } componentDidUpdate(prevProps) { if (prevProps.page !== this.props.page) { this.load(); } } render() { const users = this.state.users.map(user => ( <p key={user.id}> <img src={user.avatar} alt={user.first_name} style={{ height: 24, width: 24 }} /> {user.first_name} {user.last_name} </p> )); return <div>{users}</div>; } } Component.propTypes = { page: PropTypes.number.isRequired };
Perhatikan bahwa kita mendapatkan nilai page
melalui props
, seperti yang sering terjadi di aplikasi dunia nyata. Juga, kami memiliki fungsi componentDidUpdate
, yang mengambil kembali data API setiap kali this.props.page
berubah.
Pada titik ini, ini menunjukkan daftar enam pengguna karena API mengembalikan enam item per halaman:
Menambahkan Caching Basi-sambil menyegarkan
Jika kita ingin menambahkan caching basi-sementara-refresh ke ini, kita perlu memperbarui logika aplikasi kita ke:
- Cache respons permintaan secara unik setelah diambil untuk pertama kalinya.
- Kembalikan respons yang di-cache secara instan jika cache permintaan ditemukan. Kemudian, kirim permintaan dan kembalikan respons baru secara asinkron. Juga, cache respons ini untuk waktu berikutnya.
Kita dapat melakukan ini dengan memiliki objek CACHE
global yang menyimpan cache secara unik. Untuk keunikannya, kita bisa menggunakan nilai this.props.page
sebagai kunci pada objek CACHE
kita. Kemudian, kita cukup mengkodekan algoritma yang disebutkan di atas.
import apiFetch from "./apiFetch"; const CACHE = {}; export default class Component extends React.Component { state = { users: [] }; componentDidMount() { this.load(); } load() { if (CACHE[this.props.page] !== undefined) { this.setState({ users: CACHE[this.props.page] }); } apiFetch(`https://reqres.in/api/users?page=${this.props.page}`).then( json => { CACHE[this.props.page] = json.data; this.setState({ users: json.data }); } ); } componentDidUpdate(prevProps) { if (prevProps.page !== this.props.page) { this.load(); } } render() { // same render code as above } }
Karena cache dikembalikan segera setelah ditemukan dan karena data respons baru juga dikembalikan oleh setState
, ini berarti kami memiliki pembaruan UI yang mulus dan tidak ada lagi waktu tunggu di aplikasi sejak permintaan kedua dan seterusnya. Ini sempurna, dan ini adalah metode basi-sementara-menyegarkan secara singkat.
Fungsi apiFetch
di sini tidak lain adalah pembungkus atas fetch
sehingga kita dapat melihat keuntungan dari caching secara real time. Ini dilakukan dengan menambahkan pengguna acak ke daftar users
yang dikembalikan oleh permintaan API. Itu juga menambahkan penundaan acak untuk itu:
export default async function apiFetch(...args) { await delay(Math.ceil(400 + Math.random() * 300)); const res = await fetch(...args); const json = await res.json(); json.data.push(getFakeUser()); return json; } function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
Fungsi getFakeUser()
di sini bertanggung jawab untuk membuat objek pengguna palsu.
Dengan perubahan ini, API kami lebih nyata dari sebelumnya.
- Ini memiliki penundaan acak dalam merespons.
- Ini mengembalikan data yang sedikit berbeda untuk permintaan yang sama.
Mengingat hal ini, ketika kita mengubah prop page
yang diteruskan ke Component
dari komponen utama kita, kita dapat melihat caching API beraksi. Coba klik tombol Toggle sekali setiap beberapa detik di CodeSandbox ini dan Anda akan melihat perilaku seperti ini:
Jika Anda melihat lebih dekat, beberapa hal terjadi.
- Saat aplikasi dimulai dan dalam status default, kami melihat daftar tujuh pengguna. Catat pengguna terakhir dalam daftar karena pengguna itulah yang akan diubah secara acak saat permintaan ini dikirim lagi.
- Ketika kami mengklik Toggle untuk pertama kalinya, ia menunggu beberapa saat (400-700ms) dan kemudian memperbarui daftar ke halaman berikutnya.
- Sekarang, kita berada di halaman kedua. Sekali lagi perhatikan pengguna terakhir dalam daftar.
- Sekarang, kita klik Toggle lagi, dan aplikasi akan kembali ke halaman pertama. Perhatikan bahwa sekarang entri terakhir masih merupakan pengguna yang sama yang kita catat di Langkah 1, dan kemudian berubah menjadi pengguna baru (acak). Ini karena, pada awalnya, cache ditampilkan, dan kemudian respons yang sebenarnya muncul.
- Kami mengklik Toggle lagi. Fenomena yang sama terjadi. Respons yang di-cache dari terakhir kali dimuat secara instan, dan kemudian data baru diambil, jadi kami melihat pembaruan entri terakhir dari apa yang kami catat di Langkah 3.
Ini dia, caching basi-sementara-refresh yang kami cari. Tetapi pendekatan ini mengalami masalah duplikasi kode. Mari kita lihat bagaimana hasilnya jika kita memiliki komponen pengambilan data lain dengan caching. Komponen ini menunjukkan item secara berbeda dari komponen pertama kami.
Menambahkan Basi-sambil menyegarkan ke Komponen Lain
Kita dapat melakukan ini hanya dengan menyalin logika dari komponen pertama. Komponen kedua kami menunjukkan daftar kucing:
const CACHE = {}; export default class Component2 extends React.Component { state = { cats: [] }; componentDidMount() { this.load(); } load() { if (CACHE[this.props.page] !== undefined) { this.setState({ cats: CACHE[this.props.page] }); } apiFetch(`https://reqres.in/api/cats?page=${this.props.page}`).then( json => { CACHE[this.props.page] = json.data; this.setState({ cats: json.data }); } ); } componentDidUpdate(prevProps) { if (prevProps.page !== this.props.page) { this.load(); } } render() { const cats = this.state.cats.map(cat => ( <p key={cat.id} style={{ background: cat.color, padding: "4px", width: 240 }} > {cat.name} (born {cat.year}) </p> )); return <div>{cats}</div>; } }
Seperti yang Anda lihat, logika komponen yang terlibat di sini hampir sama dengan komponen pertama. Satu-satunya perbedaan adalah pada titik akhir yang diminta dan itu menunjukkan item daftar secara berbeda.
Sekarang, kami menunjukkan kedua komponen ini secara berdampingan. Anda dapat melihat mereka berperilaku serupa:
Untuk mencapai hasil ini, kami harus melakukan banyak duplikasi kode. Jika kita memiliki beberapa komponen seperti ini, kita akan menduplikasi terlalu banyak kode.
Untuk menyelesaikannya dengan cara yang tidak menduplikasi, kita dapat memiliki Komponen Tingkat Tinggi untuk mengambil dan menyimpan data dan meneruskannya sebagai alat peraga. Ini tidak ideal tetapi akan berhasil. Tetapi jika kita harus melakukan banyak permintaan dalam satu komponen, memiliki beberapa Komponen Tingkat Tinggi akan menjadi sangat cepat jelek.
Kemudian, kita memiliki pola render props, yang mungkin merupakan cara terbaik untuk melakukan ini di komponen kelas. Ini bekerja dengan sempurna, tetapi sekali lagi, itu rentan terhadap "pembungkus neraka" dan mengharuskan kita untuk mengikat konteks saat ini pada waktu-waktu tertentu. Ini bukan pengalaman pengembang yang hebat dan dapat menyebabkan frustrasi dan bug.
Di sinilah React Hooks menyelamatkan hari. Mereka memungkinkan kita untuk memasukkan logika komponen ke dalam wadah yang dapat digunakan kembali sehingga kita dapat menggunakannya di banyak tempat. React Hooks diperkenalkan di React 16.8 dan mereka hanya bekerja dengan komponen fungsi. Sebelum kita masuk ke React cache control—khususnya, caching konten dengan Hooks—mari kita lihat dulu bagaimana kita melakukan pengambilan data sederhana di komponen fungsi.

Pengambilan Data API di Komponen Fungsi
Untuk mengambil data API dalam komponen fungsi, kami menggunakan kait useState
dan useEffect
.
useState
analog dengan state
komponen kelas dan setState
. Kami menggunakan kait ini untuk memiliki wadah atom keadaan di dalam komponen fungsi.
useEffect
adalah kait siklus hidup, dan Anda dapat menganggapnya sebagai kombinasi dari componentDidMount
, componentDidUpdate
, dan componentWillUnmount
. Parameter kedua yang diteruskan ke useEffect
disebut larik dependensi. Saat larik dependensi berubah, panggilan balik yang diteruskan sebagai argumen pertama ke useEffect
dijalankan lagi.
Berikut adalah bagaimana kita akan menggunakan kait ini untuk mengimplementasikan pengambilan data:
import React, { useState, useEffect } from "react"; export default function Component({ page }) { const [users, setUsers] = useState([]); useEffect(() => { fetch(`https://reqres.in/api/users?page=${page}`) .then(res => res.json()) .then(json => { setUsers(json.data); }); }, [page]); const usersDOM = users.map(user => ( <p key={user.id}> <img src={user.avatar} alt={user.first_name} style={{ height: 24, width: 24 }} /> {user.first_name} {user.last_name} </p> )); return <div>{usersDOM}</div>; }
Dengan menetapkan page
sebagai dependensi ke useEffect
, kami menginstruksikan React untuk menjalankan panggilan balik useEffect kami setiap kali page
diubah. Ini seperti componentDidUpdate
. Juga, useEffect
selalu berjalan pertama kali sehingga berfungsi seperti componentDidMount
juga.
Basi-sementara-refresh di Komponen Fungsi
Kita tahu bahwa useEffect
mirip dengan metode siklus hidup komponen. Jadi kita bisa memodifikasi fungsi callback yang diteruskan ke sana untuk membuat caching basi-sementara-refresh yang kita miliki di komponen kelas. Semuanya tetap sama kecuali kait useEffect
.
const CACHE = {}; export default function Component({ page }) { const [users, setUsers] = useState([]); useEffect(() => { if (CACHE[page] !== undefined) { setUsers(CACHE[page]); } apiFetch(`https://reqres.in/api/users?page=${page}`).then(json => { CACHE[page] = json.data; setUsers(json.data); }); }, [page]); // ... create usersDOM from users return <div>{usersDOM}</div>; }
Jadi, kami memiliki caching basi-sementara-refresh yang bekerja di komponen fungsi.
Kita dapat melakukan hal yang sama untuk komponen kedua, yaitu mengubahnya menjadi berfungsi dan mengimplementasikan caching basi-saat-refresh. Hasilnya akan identik dengan apa yang kita miliki di kelas.
Tapi itu tidak lebih baik dari komponen kelas, bukan? Jadi mari kita lihat bagaimana kita bisa menggunakan kekuatan custom hook untuk membuat logika basi-sambil-refresh modular yang bisa kita gunakan di beberapa komponen.
Kait Basi-sambil-menyegarkan Kustom
Pertama, mari kita persempit logika yang ingin kita pindahkan ke custom hook. Jika Anda melihat kode sebelumnya, Anda tahu itu bagian useState
dan useEffect
. Lebih khusus lagi, ini adalah logika yang ingin kami modulasi.
const [users, setUsers] = useState([]); useEffect(() => { if (CACHE[page] !== undefined) { setUsers(CACHE[page]); } apiFetch(`https://reqres.in/api/users?page=${page}`).then(json => { CACHE[page] = json.data; setUsers(json.data); }); }, [page]);
Karena kita harus membuatnya generik, kita harus membuat URL dinamis. Jadi kita perlu memiliki url
sebagai argumen. Kami juga perlu memperbarui logika caching, karena beberapa permintaan dapat memiliki nilai page
yang sama. Untungnya, ketika page
disertakan dengan URL titik akhir, itu menghasilkan nilai unik untuk setiap permintaan unik. Jadi kita bisa menggunakan seluruh URL sebagai kunci untuk caching:
const [data, setData] = useState([]); useEffect(() => { if (CACHE[url] !== undefined) { setData(CACHE[url]); } apiFetch(url).then(json => { CACHE[url] = json.data; setData(json.data); }); }, [url]);
Itu cukup banyak. Setelah membungkusnya di dalam suatu fungsi, kami akan memiliki kait khusus kami. Lihat di bawah.
const CACHE = {}; export default function useStaleRefresh(url, defaultValue = []) { const [data, setData] = useState(defaultValue); useEffect(() => { // cacheID is how a cache is identified against a unique request const cacheID = url; // look in cache and set response if present if (CACHE[cacheID] !== undefined) { setData(CACHE[cacheID]); } // fetch new data apiFetch(url).then(newData => { CACHE[cacheID] = newData.data; setData(newData.data); }); }, [url]); return data; }
Perhatikan bahwa kami telah menambahkan argumen lain yang disebut defaultValue
. Nilai default panggilan API bisa berbeda jika Anda menggunakan hook ini di beberapa komponen. Itu sebabnya kami membuatnya dapat disesuaikan.
Hal yang sama dapat dilakukan untuk kunci data
di objek newData
. Jika kait kustom Anda mengembalikan berbagai data, Anda mungkin ingin mengembalikan data baru dan bukan newData.data
newData
menangani traversal itu di sisi komponen.
Sekarang kami memiliki kait khusus kami, yang melakukan pengangkatan berat caching basi-sambil menyegarkan, inilah cara kami menghubungkannya ke komponen kami. Perhatikan banyaknya kode yang dapat kami kurangi. Seluruh komponen kami sekarang hanya tiga pernyataan. Itu adalah kemenangan besar.
import useStaleRefresh from "./useStaleRefresh"; export default function Component({ page }) { const users = useStaleRefresh(`https://reqres.in/api/users?page=${page}`, []); const usersDOM = users.map(user => ( <p key={user.id}> <img src={user.avatar} alt={user.first_name} style={{ height: 24, width: 24 }} /> {user.first_name} {user.last_name} </p> )); return <div>{usersDOM}</div>; }
Kita dapat melakukan hal yang sama untuk komponen kedua. Ini akan terlihat seperti ini:
export default function Component2({ page }) { const cats = useStaleRefresh(`https://reqres.in/api/cats?page=${page}`, []); // ... create catsDOM from cats return <div>{catsDOM}</div>; }
Sangat mudah untuk melihat berapa banyak kode boilerplate yang dapat kita hemat jika kita menggunakan hook ini. Kode terlihat lebih baik juga. Jika Anda ingin melihat seluruh aplikasi beraksi, buka CodeSandbox ini.
Menambahkan Indikator Pemuatan ke useStaleRefresh
Sekarang setelah kita memiliki dasar-dasarnya, kita dapat menambahkan lebih banyak fitur ke kait kustom kita. Misalnya, kita dapat menambahkan nilai isLoading
di hook yang benar setiap kali permintaan unik dikirim dan sementara itu kita tidak memiliki cache untuk ditampilkan.
Kami melakukan ini dengan memiliki status terpisah untuk isLoading
dan mengaturnya sesuai dengan status hook. Artinya, ketika tidak ada konten web yang di-cache tersedia, kami menyetelnya ke true
, jika tidak kami menyetelnya ke false
.
Ini hook yang diperbarui:
export default function useStaleRefresh(url, defaultValue = []) { const [data, setData] = useState(defaultValue); const [isLoading, setLoading] = useState(true); useEffect(() => { // cacheID is how a cache is identified against a unique request const cacheID = url; // look in cache and set response if present if (CACHE[cacheID] !== undefined) { setData(CACHE[cacheID]); setLoading(false); } else { // else make sure loading set to true setLoading(true); } // fetch new data apiFetch(url).then(newData => { CACHE[cacheID] = newData.data; setData(newData.data); setLoading(false); }); }, [url]); return [data, isLoading]; }
Kita sekarang dapat menggunakan nilai isLoading
baru di komponen kita.
export default function Component({ page }) { const [users, isLoading] = useStaleRefresh( `https://reqres.in/api/users?page=${page}`, [] ); if (isLoading) { return <div>Loading</div>; } // ... create usersDOM from users return <div>{usersDOM}</div>; }
Perhatikan bahwa dengan itu selesai, Anda melihat teks "Memuat" ketika permintaan unik dikirim untuk pertama kalinya dan tidak ada cache.
Membuat useStaleRefresh
Mendukung Fungsi async
apa pun
Kami dapat membuat kait khusus kami menjadi lebih kuat dengan membuatnya mendukung fungsi async
apa pun daripada hanya GET
permintaan jaringan. Ide dasar di baliknya akan tetap sama.
- Di hook, Anda memanggil fungsi async yang mengembalikan nilai setelah beberapa waktu.
- Setiap panggilan unik ke fungsi asinkron di-cache dengan benar.
Gabungan sederhana dari function.name
dan arguments
akan berfungsi sebagai kunci cache untuk kasus penggunaan kami. Dengan menggunakan itu, ini adalah bagaimana hook kita akan terlihat:
import { useState, useEffect, useRef } from "react"; import isEqual from "lodash/isEqual"; const CACHE = {}; export default function useStaleRefresh(fn, args, defaultValue = []) { const prevArgs = useRef(null); const [data, setData] = useState(defaultValue); const [isLoading, setLoading] = useState(true); useEffect(() => { // args is an object so deep compare to rule out false changes if (isEqual(args, prevArgs.current)) { return; } // cacheID is how a cache is identified against a unique request const cacheID = hashArgs(fn.name, ...args); // look in cache and set response if present if (CACHE[cacheID] !== undefined) { setData(CACHE[cacheID]); setLoading(false); } else { // else make sure loading set to true setLoading(true); } // fetch new data fn(...args).then(newData => { CACHE[cacheID] = newData; setData(newData); setLoading(false); }); }, [args, fn]); useEffect(() => { prevArgs.current = args; }); return [data, isLoading]; } function hashArgs(...args) { return args.reduce((acc, arg) => stringify(arg) + ":" + acc, ""); } function stringify(val) { return typeof val === "object" ? JSON.stringify(val) : String(val); }
Seperti yang Anda lihat, kami menggunakan kombinasi nama fungsi dan argumennya yang dirangkai untuk mengidentifikasi panggilan fungsi secara unik dan dengan demikian menyimpannya di cache. Ini berfungsi untuk aplikasi sederhana kami, tetapi algoritme ini rentan terhadap tabrakan dan perbandingan yang lambat. (Dengan argumen unserializable, itu tidak akan bekerja sama sekali.) Jadi untuk aplikasi dunia nyata, algoritma hashing yang tepat lebih tepat.
Hal lain yang perlu diperhatikan di sini adalah penggunaan useRef
. useRef
digunakan untuk mempertahankan data melalui seluruh siklus hidup komponen terlampir. Karena args
adalah array—yang merupakan objek dalam JavaScript—setiap re-render komponen menggunakan hook menyebabkan pointer referensi args
berubah. Tetapi args
adalah bagian dari daftar ketergantungan di useEffect
pertama kami. Jadi perubahan argumen dapat membuat args
kami useEffect
bahkan ketika tidak ada yang berubah. Untuk mengatasinya, kami melakukan perbandingan mendalam antara args
lama dan saat ini menggunakan isEqual dan hanya membiarkan panggilan balik useEffect
berjalan jika args
benar-benar berubah.
Sekarang, kita dapat menggunakan hook useStaleRefresh
baru ini sebagai berikut. Perhatikan perubahan defaultValue
di sini. Karena ini adalah kait tujuan umum, kami tidak mengandalkan kait kami untuk mengembalikan kunci data
di objek respons.
export default function Component({ page }) { const [users, isLoading] = useStaleRefresh( apiFetch, [`https://reqres.in/api/users?page=${page}`], { data: [] } ); if (isLoading) { return <div>Loading</div>; } const usersDOM = users.data.map(user => ( <p key={user.id}> <img src={user.avatar} alt={user.first_name} style={{ height: 24, width: 24 }} /> {user.first_name} {user.last_name} </p> )); return <div>{usersDOM}</div>; }
Anda dapat menemukan seluruh kode di CodeSandbox ini.
Jangan Membuat Pengguna Menunggu: Gunakan Konten Cache Secara Efektif dengan Basi-sementara-refresh dan React Hooks
Hook useStaleRefresh
yang kami buat di artikel ini adalah bukti konsep yang menunjukkan apa yang mungkin dilakukan dengan React Hooks. Coba mainkan dengan kode dan lihat apakah Anda dapat memasukkannya ke dalam aplikasi Anda.
Atau, Anda juga dapat mencoba memanfaatkan basi-sementara-refresh melalui perpustakaan open-source populer yang terpelihara dengan baik seperti swr atau react-query. Keduanya adalah pustaka yang kuat dan mendukung sejumlah fitur yang membantu permintaan API.
React Hooks adalah pengubah permainan. Mereka memungkinkan kita untuk berbagi logika komponen secara elegan. Ini tidak mungkin sebelumnya karena status komponen, metode siklus hidup, dan rendering semuanya dikemas ke dalam satu entitas: komponen kelas. Sekarang, kita dapat memiliki modul yang berbeda untuk semuanya. Ini bagus untuk komposisi dan menulis kode yang lebih baik. Saya menggunakan komponen fungsi dan kait untuk semua kode React baru yang saya tulis, dan saya sangat merekomendasikan ini kepada semua pengembang React.