[React-query] Dependant Query

SoShy·2024년 5월 13일

React-Query

목록 보기
10/13
post-thumbnail

Dependant Query


🏷️ Dependant Query란?


다음 두 쿼리가 의존관계가 있어 특정 순서대로 실행이 되어야 한다고 가정해보자.

const { data: user } = useQuery({
  queryKey: ['user', email],
  queryFn: getUserByEmail,
});

const userId = user?.id

const {
  data: projects,
} = useQuery({
  queryKey: ['projects', userId],
  queryFn: getProjectsByUser,
});

이런 상황에서 useQuery()enabled 옵션을 사용할 수 있는데, enabled 옵션을 사용하면 enabled 값이 true가 되어야만 해당 쿼리가 실행된다.

이렇게, 어떤 특정 값이나 조건이 충족된 이후에 실행되는 쿼리를 Dependant Query라고 한다.

만약, 위의 쿼리가 userId 값이 있을 때만 실행하도록 하고 싶다면, 아래와 같이 코드를 작성해 볼 수 있다.


const { data: user } = useQuery({
  queryKey: ['user', email],
  queryFn: getUserByEmail,
});

const userId = user?.id

const {
  data: projects,
} = useQuery({
  queryKey: ['projects', userId],
  queryFn: getProjectsByUser,
  enabled: !!userId,
});

다만, enabled 옵션값으로 반드시 앞선 쿼리에서 가져온 데이터가 들어가야만 하는 것은 아니다.

위 예시의 경우에도 백엔드 API 설계에 따라 두 번의 쿼리가 아닌 한 번의 쿼리로 끝낼 수 있는데,

예를 들어, getProjectsByUserEmail()이라는 함수를 통해 유저의 이메일 주소를 백엔드로 전달하고, 그에 맞는 유저의 프로젝트를 받을 수 있는 API가 있다면 가능하다.

💡 enabled 옵션은 쿼리의 순서를 정하기 위해 사용하기보다는, 어떤 쿼리를 바로 실행하지 않고, 특정한 값이 있거나 특정 상황이 되었을 때 실행하도록 하는 등의 시나리오에서 활용할 수 있다.



🏷️ useQuery()에서 enabled 값 사용하기


enabled 값을 활용하여 간단한 로그인 기능을 구현한 예시 코드이다.

const BASE_URL = 'https://learn.codeit.kr/api/codestudit';

// ...

export async function getUserInfo(username) {
  const response = await fetch(`${BASE_URL}/users/${username}`);
  return await response.json();
}
import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { getPosts, uploadPost, getUserInfo } from './api';

function HomePage() {
  const [currentUsername, setCurrentUsername] = useState('');

  // ...

  const { data: userInfoData, isPending: isUserInfoPending } = useQuery({
    queryKey: ['userInfo'],
    queryFn: () => getUserInfo(currentUsername),
    enabled: !!currentUsername,
  });
  
    // ...

  const handleLoginButtonClick = () => {
    setCurrentUsername('codeit');
  };  

  const loginMessage = isUserInfoPending
    ? '로그인 중입니다...'
    : `${userInfoData?.name}님 환영합니다!`;

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

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

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

  return (
    <>
      <div>
        {currentUsername ? (
          loginMessage
        ) : (
          <button onClick={handleLoginButtonClick}>codeit으로 로그인</button>
        )}
        <form onSubmit={handleSubmit}>
          <textarea
            name="content"
            value={content}
            onChange={handleInputChange}
          />
          <button disabled={!content} type="submit">
            업로드
          </button>
        </form>
      </div>
      <div>
        <ul>
          {posts.map((post) => (
            <li key={post.id}>
              {post.user.name}: {post.content}
            </li>
          ))}
        </ul>
      </div>
    </>
  );
}

export default HomePage;
profile
프론트엔드 개발자가 되기 위해 노력 중인 새싹🌱 입니다.

0개의 댓글