[React-query] 다양한 쿼리 키와 쿼리 함수의 형태

SoShy·2024년 5월 10일

React-Query

목록 보기
6/13
post-thumbnail

🏷️ 쿼리 키가 배열 형태인 이유


이전 글에서는 포스트 전체를 받아오는 쿼리를 ['posts']라는 쿼리 키로 관리했었다.

여기서, 특정 유저의 포스트만 보여주는 기능을 추가하고자, 다음과 같은 API 함수를 만들었다고 가정해보자.

export async function getPostsByUsername(username) {
  const response = await fetch(`${BASE_URL}/posts?username=${username}`);
  return await response.json();
}

위 API 함수를 통해 받아온 데이터를 캐시에 저장할 때는, 다음과 같이, 계층적으로 쿼리 키 지정이 가능하다.

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

이렇게 하면 다음과 같이 특정 username에 대한 쿼리만 따로 캐싱이 된다.


위와 같이, 배열을 활용하여 계층적인 쿼리 키를 설정하는 것 뿐만 아니라, 상황에 따라 다양한 파라미터를 활용해 쿼리 키를 설정할 수도 있다.

예를 들어, 포스트를 나만 볼 수 있는 private 상태로 지정하는 기능을 추가한다고 가정해보자.

이 경우, 특정 유저의 포스트 중 private 상태의 포스트만 받아와서 다음과 같은 쿼리 키로 저장할 수도 있다.

const { data: postsDataByUsername } = useQuery({ 
    queryKey: ['posts', username, { status: private }], 
    queryFn: () => getPrivatePostsByUsername(username) 
});

또한, queryFn에서 argument를 전달해주어야 하는 상황이라면, 위 코드와 같이, 화살표 함수 형태를 통해 argument(username)를 전달하면 된다.

참고로, queryFn은 Promise를 리턴하는 형태라면 어떤 형태의 함수여도 상관없다.

만약, 쿼리 키에 있는 값을 argument로 전달해야 하는 상황이라면, 다음과 같이, 쿼리 함수의 파라미터로 queryKey를 전달하여, 해당 인덱스 요소를 argument로 넣어주면 된다.

const { data: postsDataByUsername } = useQuery({ 
    queryKey: ['posts', username], 
    queryFn: ({ queryKey }) => getPostsByUserId(queryKey[1]), 
});

또는, 다음과 같이, 쿼리 키에서 객체의 특정한 값을 가져와 활용하는 것도 가능하다.

const username = 'codeit';
const { data: postsDataByUsername } = useQuery({ 
    queryKey: ['posts', { username }], 
    queryFn: ({ queryKey }) => {
        const [key, { username }] = queryKey; 
        return getPostsByUserId(username);
    } 
});

주의해야 할 점은, 객체를 쿼리 키로 전달할 때는, 그 안에서는 순서에 관계없이 같은 값들을 가지고 있는 객체라면 같은 쿼리 키로 인식하지만, 배열을 쿼리 키로 전달할 때는, 요소의 순서가 중요하다는 점이다.

순서가 달라지면 다른 쿼리 키로 인식하기 때문에, 배열의 요소로 쿼리 키를 지정할 때는 순서를 꼭 확인하자.

// 다음 세 가지는 모두 같은 쿼리로 인식한다
useQuery({ queryKey: ['posts', { username, userEmail }], ... });
useQuery({ queryKey: ['posts', { userEmail, username }], ... });
useQuery({ queryKey: ['posts', { userEmail, username, other: undefined }], ... });

// 다음 세 가지는 모두 다른 쿼리로 인식한다
useQuery({ queryKey: ['posts', username, userEmail], ... });
useQuery({ queryKey: ['posts', userEmail, username], ... });
useQuery({ queryKey: ['posts', undefined, userEmail, username], ... });
profile
프론트엔드 개발자가 되기 위해 노력 중인 새싹🌱 입니다.

0개의 댓글