Gọi dữ liệu từ backend

Base sẽ sử dụng react-query sẽ xử lý cách phần data cần cache, các trạng thái loading, tự động call lại api, làm mới dữ liệu,…v.v…

UseQuery

Được sử dụng để gọi API và lưu trữ dữ liệu để render

Khi tạo 1 query cần truyền vào 1 key, các query được phân biệt với nhau dựa vào key, tiêp theo thì truyền queryFuntion, cuối cùng là option. Lưu ý: các trường hợp mà API muốn sử dụng chung dữ liệu của nhau thì sẽ khai báo trùng key với nhau

import ApiUser from "@app/api/ApiUser" // Import dưới dạng sau thay vì import thẳng những hàm gọi API cần dùng
import { useQuery } from "@tanstack/react-query"
 
const getListQuery = useQuery(
  ["list-query"], // Key cho dữ liệu của API để lưu trong cache
  ApiUser.getUserAccount, // Hàm gọi API định nghĩa trong folder API (Đọc 1. API.md)
  {
    // Các option có thể xem ở đây https://react-query-v3.tanstack.com/reference/useQuery
    enabled: false,
    refetchOnWindowFocus: false,
  },
)
 
const {
  data, // Dữ liệu sau khi API trả về
  isLoading, // Sẽ bằng true khi đăng gọi API
  isError, // Sẽ bằng true khi API trả về lỗi
} = getListQuery
 
getListQuery.refetch() // Gọi hàm này để gọi API

Vi dụ: Để truyền tham số params vào để gọi API, ta có thể làm như sau

const getFollowUser = (): Promise<IFollow> => ApiFollow.checkFollow(newsData?.author?._id)
 
const followUser = useQuery("followDetails" + id, getFollowUser)

hoặc

const getUserAccount = (): Promise<IUserLogin[]> => {
  return ApiUser.getUserAccount({ pageSize: 30, pageNumber: 1 })
}
 
const listUserAccount = useQuery("listUserAccount", getUserAccount)

UseInfiniteQuery

Cũng giống như useQuery nhưng thêm phần load thêm dữ liệu ở trang tiếp theo (Hay sử dụng cho các chỗ list dữ liệu như Table)

Các tùy chọn cho useInfiniteQuery giống hệt với hook useQuery nhưng sẽ có bổ sung các tùy chọn sau:

getNextPageParam: (lastPage) => {
  if (lastPage?.data?.length !== 0) {
    return (lastPage?.meta.currentPage || 0) + 1
  }
  return undefined
}
  • Viết hàm này để trả về tham số lấy dữ liệu cho trang tiếp cho lần gọi API tiếp theo
  • Trả lại undefined nếu không muốn lấy trang tiếp theo
getPreviousPageParam: (lastPage) => {
  if (lastPage?.previousPage !== 0) {
    return lastPage.previousPage
  }
  return undefined
}
  • Viết hàm này để trả về tham số lấy dữ liệu cho trang tiếp cho lần gọi API tiếp theo
  • Trả lại undefined nếu không muốn lấy trang trước

EXAMPLE:

const getNewsMoreForYou = ({
  pageParam = 1, // Thông số truyền vào để gọi API
}): Promise<IDataWithMeta<INewsItem[]>> => {
  return ApiNews.getUserNewsMoreForYou({
    page: pageParam,
    pageSize: 20,
  })
}
 
const newsDataMoreForYou = useInfiniteQuery("newsMoreForYou", getNewsMoreForYou, {
  getNextPageParam: (lastPage) => {
    if (lastPage?.data?.length !== 0) {
      return (lastPage?.meta.currentPage || 0) + 1 // Trả về trang tiếp theo
    }
    return undefined
  },
  enabled: false,
})
 
newsDataMoreForYou.refetch() // Gọi hàm này để lấy trang dữ liệu đầu tiên
newsDataMoreForYou.fetchNextPage() // Gọi hàm này để lấy trang dữ liệu tiếp theo
Sửa dữ liệu trong query dùng hàm setQueryData
example:
    queryClient.setQueryData(
        "detailNews" + id,
        (queryData) =>
            queryData && {
                ...newsData,
            }
    );
Nó sẽ nhận 1 key là "detailNews" nếu có queryData nó sẽ trả về newsData còn kh có queryData nó sẽ trả về null.