Installation
Để sử dụng React Query, trước tiên ta cần cài đặt hai package sau đây:
yarn add @tanstack/react-query @tanstack/react-query-devtoolsPackage thứ hai là của React Query DevTools.
Setup
Import các thành phần cần thiết từ @tanstack/react-query:
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"Trước tiên, tạo ra một query client thông qua constructor của QueryClient như sau:
const queryClient = new QueryClient()Bọc component QueryClientProvider ở bên ngoài App với client là queryClient vừa tạo ở trên như sau:
createRoot(document.getElementById("root")).render(
<StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</StrictMode>,
)Tiếp theo, import ReactQueryDevtools và chèn ở sau component App như sau:
// Existing import ...
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
createRoot(document.getElementById("root")).render(
<StrictMode>
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools />
</QueryClientProvider>
</StrictMode>,
)Query
Để tạo một query giúp thực hiện truy vấn dữ liệu, ta cần dùng hook useQuery từ @tanstack/react-query.
import { useQuery } from "@tanstack/react-query"Hook này nhận vào một object, bao gồm hai thuộc tính quan trọng:
queryKey: là một mảng gồm nhiều giá trị dùng để định danh cho query. Hoạt động tương tự như tag của RTK Query (xem thêm Automated Re-fetching in RTK Query).queryFn: là một callback thực hiện gửi request đến API và trả về một Promise có chứa dữ liệu.
Ví dụ:
const productsQuery = useQuery({
queryKey: ["products"],
queryFn: async () => {
const res = await axios.get(`${API}/products`)
return res.data
},
})Giá trị trả về của useQuery là một query, bao gồm các thuộc tính quan trọng sau:
data: kết quả trả về của query.error: lỗi của query.status: trạng thái của query, bao gồm các giá trị:loading,successvàerror.isLoading,isSuccessvàisError: các trạng thái của query ở dạng boolean.fetchStatus: trạng thái của fetching, bao gồm các giá trị :fetching,idlevàpaused1.
Gọi sử dụng query productsQuery ở trên như sau:
function App() {
const productsQuery = useQuery({
// ...
})
if (productsQuery.isLoading) return <h1>Loading...</h1>
if (productsQuery.isError) {
return <pre>{JSON.stringify(productsQuery.error)}</pre>
}
return (
<div>
{productsQuery.data.map((product) => (
<div key={product.productId}>{product.name}</div>
))}
</div>
)
}Mutation
Để tạo ra một mutation giúp thực hiện các mutation request (là các request thực hiện thay đổi dữ liệu), ta cần dùng hook useMutation từ @tanstack/react-query:
import { useMutation } from "@tanstack/react-query"Hook này cũng nhận vào một object tương tự như useQuery. Thuộc tính mutationFn của object giúp chỉ định callback thực hiện gửi mutation request.
Ví dụ:
const updateProductPriceMutation = useMutation({
mutationFn: async (newPrice) => {
const product = productQuery.data
const body = { ...product, price: newPrice }
const res = await axios.put(`${API}/products/${productId}`, body)
return res.data
},
})Giá trị trả về của useMutation là một mutation mà có các thuộc tính tương tự như một query chẳng hạn như data, error, isLoading, isError, …
Gọi sử dụng mutation ở trên như sau:
<button
disabled={updateProductPriceMutation.isLoading}
onClick={() => {
updateProductPriceMutation.mutate(Math.floor(Math.random() * 100))
}}
>
Random a new price
</button>Resources
Footnotes
-
React Query coi loading và fetching là hai quá trình khác nhau, tương tự như RTK Query (xem thêm Queries in RTK Query). ↩