Bài viết được sự cho phép của tác giả Lưu Bình An
React-query sẽ giúp chúng ta giải quyết các vấn đề sau
- Một global context để lưu trữ dữ liệu lấy về từ server
- Thiết đặt Caching đơn giản
Xem thêm chương trình tuyển dụng React hấp dẫn trên TopDev
Nếu thích bạn cũng có thể tham khảo thêm swr cũng khá cool
Chúng ta sẽ có các Server side APIs sau
// api/product.js
// 1. Fetch tất cả products
const useFetchProducts = () => {}
// 2. Fetch một product cụ thể
const useFetchProduct = (id) => {}
// 3. Thêm một product
const useAddProduct = (product) => {}
// 4. Cập nhập một product
const useEditProduct = (product) => {}
// 5. Xóa một product
const useDeleteProduct = (id) => {}
Thực hiện fetch với useQuery
import { useQuery } from 'react-query'
const useFetchProducts = () => {
return useQuery(
// định danh
'products', () => {
fetch('/api/products')
}
)
}
Sử dụng trong component
import { useFetchProducts } from "../api/products"
const Products = () => {
const {
data: products,
isLoading
} = useFetchProducts();
return (
<div>
{
isLoading && <div>Loading...</div>
}
{
products && (
products.map((product) => {
<div key={product.id}>
{product.name}
</div>
})
)
}
</div>
)
}
Việc fetch
dữ liệu sẽ còn thêm các tính năng như search, phân trang, filter. Có react-query mọi thứ sẽ vô cùng đơn giản
import { useState } from "react"
import { useFetchProducts } from "../api/products"
const Products = () => {
// trang hiện tại
const [page, setPage] = useState(1)
// số item trên trang
const [limit, setLimit] = useState(10)
// từ khóa
const [name, setName] = useState('')
const {
data: products,
isLoading
} = useFetchProducts({
page, limit, name });
return (
<div>
{
isLoading && <div>Loading...</div>
}
{
products && (
products.map((product) => {
<div key={product.id}>
{product.name}
</div>
})
)
}
</div>
)
}
Chúng ta cần cập nhập lại useFetchProducts
import { useQuery } from 'react-query'
const useFetchProducts = ({ page, limit, name }) => {
return useQuery(
['products', { page, limit, name }], () => {
fetch(`/api/products?page=${page}&limit=${limit}&search=${name}`) }
)
}
Thực hiện cache
Ví dụ chúng ta muốn đặt cache 10s, chúng ta sẽ sử dụng thiết đặt staleTime
import { useQuery } from 'react-query'
const useFetchProducts = ({ page, limit, name }) => {
return useQuery(
['products', { page, limit, name }],
() => {
fetch(`/api/products?page=${page}&limit=${limit}&search=${name}`)
},
{
staleTime: 10000 }
)
}
Cực kỳ đơn giản đúng không!
Tưởng tượng chúng ta có danh sách product hiển thị trên màn hình, click vào một product chúng ta hiển thị pop-up với các thông tin của product
Để fetch
một product, chúng ta cũng đồng thời áp dụng cache
const useFetchProduct = (id) => {
return useQuery(
['product', id],
() => {
fetch(`/api/products/${id}`)
},
{
staleTime: 10000
}
)
}
Đến phần thú vị nè, nếu các thông tin của từng product hoàn toán giống với thông tin trả về từ danh sách product?, chúng ta có thể áp dụng cache cho từng product trong lúc fetch danh sách product
import { useQuery, useQueryClient } from 'react-query'
const useFetchProducts = ({ page, limit, name }) => {
const queryClient = useQueryClient();
return useQuery(
['products', { page, limit, name }],
() => {
fetch(`/api/products?page=${page}&limit=${limit}&search=${name}`)
},
{
staleTime: 10000,
onSuccess: (products) => { products.forEach(product => {
queryClient.setQueryData( ['product', product.id],
product
);
})
}
}
)
}
Bằng cách dùng useQueryClient().setQuery
, chúng ta force cache cho từng product.id
, để khi useFetchProduct
chạy nó sẽ có sẵn giá trị cache này và không cần thực hiện gọi API
Thể hiện chút tình yêu với dự án react-query
nhé các bạn, star ngay không nói nhiều
Bài viết gốc được đăng tải tại vuilaptrinh.com
Có thể bạn quan tâm:
- Phương pháp test React Component
- Làm sao để fetch dữ liệu bằng React Hook
- Vấn đề của React Context trên các xử lý async
Xem thêm Việc làm IT hấp dẫn trên TopDev