[React-Query] Query-key

상민·2022년 7월 16일
0

React Query

목록 보기
3/6
post-thumbnail

useQuery 실습

지난 실습에 이어서 이번에는 각 post의 comment를 받아오는 useQuery훅을 작성해보자

  • src/PostDetail.tsx

interface IPostDetailProps {
  post: IPost;
}
interface IComments {
  id: number;
  email: string;
  body: string;
}

async function fetchComments(postId: number) {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/comments?postId=${postId}`
  );
  return response.json();
}

export function PostDetail({ post }: IPostDetailProps) {
  // replace with useQuery
  const {data, isLoading, isError}  = useQuery<IComments[]>('comments', () => fetchComments(post.id));
 // fetchComments는 postId를 인자로 받기 때문에 익명함수로 감싸서 작성한다
  return (
    <>
      <h3 style={{ color: "blue" }}>{post.title}</h3>
      <button>Delete</button> <button>Update title</button>
      <p>{post.body}</p>
      <h4>Comments</h4>
      {
        isError && <div>ERROR!</div>
      }
      {
        isLoading ?(
          <div>Loading...</div>
        ) : (
          data?.map((comment) => (
            <li key={comment.id}>
              {comment.email}: {comment.body}
            </li>
          ))
        )
      }
    </>
  );
}

comments를 잘 받아오지만 문제가 있다.
다른 게시글을 클릭해도 처음 받아온 comment를 보여준다.

왜 같은 comment를 계속 보여줄까?

이유는 모든 쿼리가 comments 쿼리 키를 동일하게 사용하고 있기 때문이다.

이렇게 comments 같이 알려진 쿼리 키가 있을 때는 어떠한 트리거가 있어야만 데이터를 다시 가져오게 된다

  • 컴포넌트를 다시 마운트할 때
  • 윈도우를 다시 포커스할 때
  • useQuery에서 반환되어 수동으로 리페칭을 실행할 때
  • 지정된 간격으로 리페칭을 자동 실행할 때
  • Mutation을 생성한 뒤 쿼리를 무효화할 시 클라이언트의 데이터가 서버의 데이터와 불일치할 때

새 게시물 제목을 클릭할 때는 이런 트리거가 일어나지 않기 때문에 data refetch가 일어나지 않는 것이다.

해결방법

각 게시물 쿼리에 대한 라벨을 설정한다

각 쿼리에 대한 라벨을 설정하면 comments 쿼리에 대한 캐시를 공유하지 않고 각 쿼리에 해당하는 캐시를 가지게 될 것이다.

쿼리 키에 문자열 대신 배열을 전달한다
['comments', post.id]

쿼리 키를 쿼리에 대한 의존성 배열로 취급하게 된다.

이렇게 하면 모든 comments 쿼리가 같은 쿼리로 간주되는 상황을 막고 각기 다른 쿼리로 다뤄질 것이다.

  • src/PostDetail.tsx

interface IPostDetailProps {
  post: IPost;
}
interface IComments {
  id: number;
  email: string;
  body: string;
}

async function fetchComments(postId: number) {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/comments?postId=${postId}`
  );
  return response.json();
}

export function PostDetail({ post }: IPostDetailProps) {
  // replace with useQuery
  const {data, isLoading, isError}  = useQuery<IComments[]>(['comments', post.id], () => fetchComments(post.id));
 // fetchComments는 postId를 인자로 받기 때문에 익명함수로 감싸서 작성한다
 // 쿼리 키를 의존성 배열로 작성하여 post.id마다 각기 다른 쿼리를 생성
  return (
    <>
      <h3 style={{ color: "blue" }}>{post.title}</h3>
      <button>Delete</button> <button>Update title</button>
      <p>{post.body}</p>
      <h4>Comments</h4>
      {
        isError && <div>ERROR!</div>
      }
      {
        isLoading ?(
          <div>Loading...</div>
        ) : (
          data?.map((comment) => (
            <li key={comment.id}>
              {comment.email}: {comment.body}
            </li>
          ))
        )
      }
    </>
  );
}

각 게시물마다 다른 comment 쿼리를 가진다

profile
FE Developer

1개의 댓글

comment-user-thumbnail
2025년 4월 12일

Seeking an escape that's truly tailored to you? The elegance of Escort in Hotel awaits. Imagine personalized attention, stimulating conversation, and sensual delights, all crafted to match your unique desires. It's about indulging in a world where your pleasure is paramount, and every detail is designed to create an unforgettable experience. Step into your fantasy.
Escorts Near Hotel Surya International Karol Bagh
Escorts Service in Taj Mahal Hotel Man Singh Road
Escorts in Taj City Centre Hotel
Hotel Taurus Sarovar Portico Escorts Service
Escorts Service Near Taj Palace Hotel

답글 달기