react-Query

Jinmin Kim·2025년 1월 3일
0

1. useQuery - 서버 데이터 가져오기

useQuery({ queryKey, queryFn, ...options });

const { data, isPending, isError, error } = useQuery({
  queryKey: [QUERY_KEY],  // 식별자
  queryFn: QUERY_FUNCTION // HTTP 요청 함수 (Promise를 반환하는 함수)
});

1-1.queryClient.getQueryData로 즉시 캐싱된 데이터 가져오기

import { useQueryClient } from "@tanstack/react-query";

const CachedUsers = () => {
  const queryClient = useQueryClient();

  // 캐싱된 데이터 가져오기
  const cachedUsers = queryClient.getQueryData(["users"]);

  if (!cachedUsers) return <p>No cached data available.</p>;

  return (
    <ul>
      {cachedUsers.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
};

getQueryData는 React Query의 캐싱 데이터를 반환합니다. 데이터가 없으면 undefined를 반환합니다.
서버에 요청하지 않으므로 빠르게 데이터를 접근할 수 있습니다.

1-2.캐싱된 데이터를 갱신하는 방법

캐싱된 데이터를 수동으로 갱신하려면 queryClient.setQueryData를 사용합니다.

예제: 데이터 갱신

const updateCachedUsers = () => {
  const queryClient = useQueryClient();

  queryClient.setQueryData(["users"], (oldData) => {
    if (!oldData) return [];
    return [...oldData, { id: 3, name: "New User" }];
  });
};

1-3.유효하지 않은 데이터 처리

캐싱된 데이터를 무효화하려면 queryClient.invalidateQueries를 사용합니다.

const invalidateUsers = () => {
  const queryClient = useQueryClient();
  queryClient.invalidateQueries(["users"]); // 캐싱된 데이터를 무효화하고 다시 요청
};

1-4.캐싱된 데이터가 없을 때의 처리

queryClient.getQueryData를 사용해 데이터를 확인하고, 데이터가 없을 경우 서버 요청으로 데이터를 가져오도록 처리합니다.

const UsersWithFallback = () => {
  const queryClient = useQueryClient();
  const cachedUsers = queryClient.getQueryData(["users"]);

  const { data } = useQuery(["users"], fetchUsers, {
    enabled: !cachedUsers, // 캐싱된 데이터가 없을 때만 fetchUsers 호출
    initialData: cachedUsers, // 캐싱된 데이터를 초기값으로 설정
  });

  return (
    <ul>
      {data.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
};

enabled: 쿼리 실행 조건을 설정. 캐싱된 데이터가 없을 때만 실행.
initialData: 초기 데이터를 설정. 캐싱된 데이터를 초기값으로 제공.

파라미터를 넘겨줄수 없을때 수동 호출

const useTradeDetail = (trade_connect_key) => {
  return useQuery(['getTradeDetail', trade_connect_key], () => fetchTradeDetail(trade_connect_key), {
    enabled: false, // 초기화 시 자동 호출 방지
  });
};

const { data, isLoading, isError, refetch } = useTradeDetail(tradeKey);

const handleFetch = () => {
  refetch(); // 수동으로 데이터 호출
};

쿼리 함수에 파라미터 넘기는 방법

React Query는 두 번째 인자인 Query Function을 호출할 때, queryKey 전체를 인자로 전달합니다.

const fetchTradeDetail = async ({ queryKey }) => {
  const [_, trade_connect_key] = queryKey; // queryKey에서 값 추출
  const response = await fetch(`/api/trade/${trade_connect_key}`);
  return response.json();
};

동적으로 Get 요청이 필요할때

  • useQuery를 사용해야 할 때
  1. 데이터가 캐싱이 필요하거나, 자동 갱신이 요구될 때.
  2. 동일한 데이터를 여러 컴포넌트에서 재사용할 때.
  3. 주기적인 데이터 동기화가 필요한 경우.
  • useMutation을 사용해도 되는 경우
  1. 데이터 호출이 동적으로 제어되어야 하고, 한 번의 호출로 끝나는 경우.
  2. 캐싱 및 상태 관리가 필요 없는 단순한 요청일 때.
  3. API 호출의 목적이 단순히 데이터를 가져오기만 하는 것이 아닌, 사용자 상호작용과 밀접하게 연결되어 있을 때.

2. useMutation - 서버 데이터 변경하기

서버 데이터를 변경하는 요청을 처리하며, 일반적으로 POST, PUT, DELETE 요청에 사용됩니다.
React Query의 캐싱과 쿼리 무효화를 활용해 데이터 동기화를 자동화할 수 있습니다.


onSuccess, onError, onSettled
  • 콜백 함수
  1. onMutate: 변이가 실행되기 직전에 호출됩니다. 낙관적 업데이트(Optimistic Update)에 사용됩니다.

  2. onSuccess: 변이가 성공적으로 완료된 후 실행됩니다.
    onSuccess 콜백은 세 개의 인자를 받습니다
    data: 서버로부터 응답받은 response
    variables: 요청 시 전달한 파라미터 (즉, onMutate에서 사용했던 newData와 동일)
    context: onMutate에서 반환한 값

  3. onError: 변이 도중 에러가 발생했을 때 실행됩니다.

  4. onSettled: 성공/실패 여부와 관계없이 항상 실행됩니다.

const mutation = useMutation(addUser, {
  onMutate: async (newUser) => {
    await queryClient.cancelQueries(["users"]);
    const previousUsers = queryClient.getQueryData(["users"]);

    queryClient.setQueryData(["users"], (old) => [...old, newUser]);

    return { previousUsers };
  },
  onError: (err, newUser, context) => {
    queryClient.setQueryData(["users"], context.previousUsers);
  },
  onSuccess: (data, variables, context) => {
    queryClient.invalidateQueries(["users"]);
  },
  onSettled: () => {
    queryClient.invalidateQueries(["users"]);
  },
});

1) 낙관적 업데이트
데이터를 서버에 요청하기 전에 UI를 미리 업데이트하여 사용자 경험을 개선합니다.

onMutate: (newUser) => {
  const previousUsers = queryClient.getQueryData(["users"]);
  queryClient.setQueryData(["users"], (old) => [...old, newUser]);
  return { previousUsers };
},

핵심: 무효화와 자동 리패칭의 과정!

3. useInfiniteQuery - 무한스크롤

DevTools 용어

profile
Let's do it developer

0개의 댓글

관련 채용 정보