리액트 쿼리 기초

LEE GYUHO·2024년 1월 16일
0

Status

  • Query Status: query status는 세 가지 상태값을 가진다.
    • pending: 아직 데이터를 받아오지 못했을 때
    • success: 데이터를 성공적으로 받아올 때
    • error: 데이터를 받아오는 중 에러가 발생했을 때
  • Fetch Status: fetch status는 세 가지 상태 값을 가진다.
    • fetching: 현재 쿼리 함수(queryFn)가 실행되고 있는 중일 때
    • paused: 쿼리 함수가 시작은 했는데 실제로 실행되고 있지 않을 때
    • idle: 쿼리 함수가 어떤 작업도 하고 있지 않는 상황(fetching 상태도 아니고 paused 상태도 아닌 경우)

캐시

  • queryKey로 캐시에 저장되어 있는 것을 확인할 수 있다.

  • useQuery()는 쿼리 키로 캐시에 저장된 데이터가 있는지 확인 후 저장된 데이터가 없으면 쿼리 함수를 실행하여 데이터를 받아온 후 쿼리 키로 데이터를 캐시에 저장한다.

  • 저장된 데이터가 있다면 그 데이터를 리턴한다.

    • 데이터가 fresh 상태라면 캐시에 저장된 데이터 리턴.
    • 데이터가 stale 상태라면 백그라운드에서 refetch를 진행. 그리고 캐시되어 있던 데이터 갱신
    • refetch 옵션
      • refetchOnMount: 새로운 쿼리 인스턴스가 마운트될 때
      • refetchOnWindowFocus: 브라우저 창에 다시 포커스가 갈 때
      • refetchOnReconnect: 네트워크가 다시 연결될 때
      • refetchInterval: 미리 설정해 둔 refetch interval 시간이 지났을 때
  • Stale Time

    • 디폴트 값은 0이다.
  • Garbage Collection Time

    • 쿼리 컴포넌트가 언마운트 되어 해당 데이터가 쓰이지 않는 상황이 되면 inactive 상태가 된다. 그리고 garbage collection time이 지나면 캐시에서 삭제된다.
    • 디폴트 값은 5분이다.
  • 라이프 사이클

  • 특정 데이터만 따로 저장

function HomePage() {
  const username = 'codeit'; // 임의로 username을 지정
  const { data: postsDataByUsername } = useQuery({
    queryKey: ['posts', username],
    queryFn: () => getPostsByUsername(username),
  });
  console.log(postsDataByUsername);
  
  return <div>홈페이지</div>;
}

로딩과 에러 처리 옵션

  • isPending, isError
function HomePage() {
  const {
    data: postsData,
    isPending,
    isError,
  } = useQuery({
    queryKey: ['posts'],
    queryFn: getPosts,
    retry: 0,
  });

  if (isPending) return '로딩 중입니다...';

  if (isError) return '에러가 발생했습니다.';

  const posts = postsData?.results ?? [];

  return (
    <div>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>
            {post.user.name}: {post.content}
          </li>
        ))}
      </ul>
    </div>
  );
}
  • 리액트 쿼리에서 에러가 발생하면 기본적으로 재시도 3번을 한다.
    • 이 옵션을 수정하고 싶으면 retry 횟수를 조정하면 된다.
function HomePage() {
  const {
    data: postsData,
    isPending,
    isError,
  } = useQuery({
    queryKey: ['posts'],
    queryFn: getPosts,
    retry: 0,
  });

useMutation

  • useMutation()과 useQuery()의 차이점

    • useQuery()의 쿼리 함수는 컴포넌트가 마운트되면서 자동으로 실행되지만, useMutation()은 실제로 뮤테이션하는 함수를 직접 실행해 줘야 한다.
    • mutate() 함수를 통해 mutationFn으로 등록했던 함수를 실행할 수 있고, 그래야만 백엔드 데이터를 실제로 수정할 수 있다.
  • useMutation() 훅을 이용해 새로운 데이터를 추가해도 캐시에 있는 데이터가 업데이트 되지 않기 때문에 자동으로 refetch 시켜주는 invalidateQueries()를 사용해줘야 한다.

    • 쿼리를 invalidate하면 해당 쿼리를 통해 받아 온 데이터를 stale time이 지났는지 아닌지에 상관없이 무조건 stale 상태로 만들고, 해당 데이터를 백그라운드에서 refetch하게 된다.
    • 뮤테이션이 성공한 시점에 쿼리를 invalidate 해주는 함수를 콜백으로 등록
    import { useQueryClient } from '@tanstack/react-query'
    
     const queryClient = useQueryClient();
    
     // ...
    
     queryClient.invalidateQueries();

    
    const queryClient = useQueryClient();
    
    // ...
    
    const uploadPostMutation = useMutation({
      mutationFn: (newPost) => uploadPost(newPost),
      onSuccess: () => {
        queryClient.invalidateQueries({ queryKey: ['posts'] });
      },
    });
    
  • useMutation() 함수의 콜백 옵션

    • onMutate
    • onSuccess
    • onError
    • onSettled
  • mutate() 함수의 콜백 옵션

    • onMutate
    • onSuccess
    • onError
    • onSettled
  • useMutation()에 등록된 콜백이 먼저 실행 그 후 mutate()에 등록한 콜백 함수 실행

    • useMutation()에 등록된 콜백 함수들은 컴포넌트가 언마운트되더라도 실행이 되지만, mutate()의 콜백 함수들은 만약 뮤테이션이 끝나기 전에 해당 컴포넌트가 언마운트되면 실행되지 않는다.
profile
누구나 같은 팀으로 되길 바라는 개발자가 되자

0개의 댓글

관련 채용 정보