Pandaman Blog

[React Query] Default Query Function 본문

Front end/React-Query

[React Query] Default Query Function

oyg0420 2022. 5. 15. 15:28

1. Default Query Function

https://codesandbox.io/s/default-query-function-yeje-wyfbxm?file=/src/index.js 

 

Default Query Function 예제 - CodeSandbox

Default Query Function 예제 by oyg0420 using axios, react, react-dom, react-query, react-scripts, stop-runaway-react-effects, styled-components

codesandbox.io

동일한 쿼리 기능을 공유하고 쿼리 키를 사용하여 가져와야 할 항목을 식별할 수 있기를 원하는 경우 default query function 기능을 사용할 수 있다.

만약 리스트 호출하는 API와 그 상세에 해당하는 API가 아래와 같다고 가정해보자.

https://jsonplaceholder.typicode.com/posts
https://jsonplaceholder.typicode.com/posts/:id

위와 같은 API를 useQuery를 사용한다면 각각 아래와 같이 사용할 수 있다.

const fetchPosts = async () => {
  const { data } = await axios.get(
    'https://jsonplaceholder.typicode.com/posts'
  );
  return data;
};

const fetchPost = async (postId) => {
  const { data } = await axios.get(
    `https://jsonplaceholder.typicode.com/posts/${postId}`
  );
  return data;
};

const queryClient = new QueryClient();

const { status, data, error, isFetching } = useQuery("posts", () => fetchPosts());
const { status, data, error, isFetching } = useQuery(["posts", postId], () => fetchPost(postId));

fetchPosts, fetchPost 각각 정의했다. queryClient 인스턴스를 생성하고 useQuery를 사용하여 queryKey와 queryFn을 할당했다.
여기서 더 간소화시킬 수 있을까?(간소화되었다고 좋은 건 아니지만) 그렇다.
fetchPosts와 fetchPost를 한 개의 비동기 함수로 만들어보자.

const fetchPosts = async () => {
  const { data } = await axios.get(
    'https://jsonplaceholder.typicode.com/posts'
  );
  return data;
};

const fetchPost = async (postId) => {
  const { data } = await axios.get(
    `https://jsonplaceholder.typicode.com/posts/${postId}`
  );
  return data;
};

const defaultFetchPost = async ({ queryKey }) => {
  if (queryKey[0] === "posts") {
    return await fetchPosts();
  } else {
    const postId = queryKey[1];
    return await fetchPost(postId);
  }
};

const queryClient = new QueryClient();

const { status, data, error, isFetching } = useQuery("/posts", defaultFetchPost);
const { status, data, error, isFetching } = useQuery(`/posts/${postId}`, defaultFetchPost);

변경된 점은 useQuery에 두 번째 인자(queryFn)에 defaultFetchPost를 할당했다. defaultFetchPost의 인자인 queryKey는 Array이고 useQuery의 첫 번째 인자 queryKey에 해당한다. queryKey [0]가 "posts"인 경우는 fetchPosts를 호출, 아닌 경우는 fetchPost를 호출하도록 수정했다. defaultFetchPost가 useQuery에 중복으로 할당된 것을 확인할 수 있다. 이때 사용되는 option이 바로 defaultOptions이며 여기서 queryFn을 정의할 수 있다. queryFn을 정의하면 동일한 쿼리 기능을 공유할 수 있다.

const defaultFetchPost = async ({ queryKey }) => {
  if (queryKey[0] === "posts") {
    return await fetchPosts();
  } else {
    const postId = queryKey[1];
    return await fetchPost(postId);
  }
};

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      queryFn: defaultFetchPost
    }
  }
});

const { status, data, error, isFetching } = useQuery("/posts");
const { status, data, error, isFetching } = useQuery(`/posts/${postId}`);

좀 깔끔해졌다. 이렇게 동일한 쿼리 기능을 공유하고 싶은 경우에는 defaultOptions을 사용을 고려해볼 필요가 있다.

'Front end > React-Query' 카테고리의 다른 글

[React Query] Pagination과 Infinite Scroll  (0) 2022.05.14
[React Query] Query / Mutation 이해하기  (0) 2022.04.11
Comments