[React] React Query

조수현·2025년 9월 21일

서론

경력 기술서 작성하는데 리액트 쿼리 안 쓴 지 오래돼서 면접 때 물어보면 곤란해지기 때문에 공부하고 가려고 적는 글

참고

React query란

데이터를 api 호출로 페칭하고 관리하는 라이브러리

  • 대량의 데이터를 불러와 새로고침 할 때마다 매번 데이터를 불러오면 앱이 느려지고 성능이 저하된다
  • 이미 불러왔던 데이터를 캐시에 저장해 사용하면 성능에 큰 도움이 된다
  • 이 때 데이터를 캐싱하고 변경된 데이터를 관리하는데 도움을 주는 라이브러리이다.

주요 기능

  • 데이터 패칭 (성공, 실패, 로딩 상태 관리)
  • 데이터 페이지 네이션
  • 데이터 캐싱

tanstack query

  • react-qeury를 좀 더 편리하게 사용할 수 있는 라이브러리
  • 최근에는 react query하면 tanstack의 react-query 라이브러리를 지칭함

기본 형태

설치

npm i @tanstack/react-query

query client 와 provider 설정

리액트 쿼리를 사용할 컴포넌트를 provider로 감싸고 react query 객체를 전달한다

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

function App() {
  const queryClient = new QueryClient();

  return (
    <QueryClientProvider client={queryClient}>
      // 여기에 들어오는 컴포넌트에서 react query 사용 가능
    </QueryClientProvider>
  );
}

export default App;

기존 데이터 패칭

  const { isPending, data, error } = useQuery({
    queryKey: ["데이터에-키값을-부여해-관리에-사용"],
    queryFn: Promise객체데이터를반환하는함수,
  });

queryKey

  • 데이터 구분 키, 배열로 전달 된다
  • 배열 그대로 stringify 처리되어 키가 된다
  • 키에 따라 구분하여 캐시를 한다
  • 같은 키를 사용하면 키에 해당하는 데이터를 조회함

queryFn

  • Promise 객체를 반환하는 데이테 호출 함수를 넣는다
  • try catch 문 없이 throw new Error와 같이 에러 예외 처리 시 useQuery에서 처리해 준다

페이지 네이션

  • 나는 react query를 사용해 캐시보다도 페이지 네이션 기능을 더 많이 활용했다
  • query key에 page변수를 추가하면 page마다 캐시 처리
  • 전에 불러왔던 페이지는 재조회 시 빠르게 렌더링 가능

useInfiniteQuery

  • 페이지 별로 데이터를 불러오는 게 아닌 불러온 데이터 다음 데이터를 추가로 불러오는 로직, 예를 들면 infinity scroll의 형태를 구현할 때 사용하는 hook이다
  • queryFn이 pageParam이라는 프로퍼티를 받아 다음 페이지 호출에 사용한다
  const fetchFunction = async ({ pageParam }) => {
    const response = await fetch('/api/page=' + pageParam)
    return response.json()
  }

  const {
    data,
    error,
    fetchNextPage,
    hasNextPage,
    isFetching,
    isFetchingNextPage,
  } = useInfiniteQuery({
    queryKey: ['query-key'],
    queryFn: fetchFunction,
    initialPageParam: 0,
    getNextPageParam: (lastPage, pages) => lastPage.end_key,
  })
  • fetchNextPage: 함수 호출 시 다음 페이지를 불러온다

  • hasNextPage: 다음 페이지가 있는지 확인하는 변수

  • getNextPageParam: queryFn에 넘겨줄 pageParams를 반환하는 함수

적용

실제 프로젝트에서는 아직 대량의 데이터가 없어서 ㅎㅎ dummy json으로 테스트 하겠습니다~

적용 전 코드

  const [users, setUsers] = useState([]);

  const fetchDummyData = async () => {
    try {
      const response = await fetch("https://dummyjson.com/users").then((res) =>
        res.json()
      );

      if (!response) throw new Error("no data");

      setUsers(response.users);
      return response.users;
    } catch (error) {
      console.error(error);
    }
  };

  const prepareUsers = async () => {
    const users = await fetchDummyData();
    setUsers(users);
  };

  useEffect(() => {
    prepareUsers();
  }, []);

코드

  • hook을 사용하니 데이터, 통신 상태에 관련된 상태 관리를 따로 하지 않아도 되어 코드가 간결해짐
  • 캐시 관련된 로직이 작성되어 있었다면 더 간결하게 작성 가능
  const fetchDummyData = async () => {
    try {
      const response = await fetch("https://dummyjson.com/users").then((res) =>
        res.json()
      );

      if (!response) throw new Error("no data");

      return response.users;
    } catch (error) {
      console.error(error);
    }
  };


  const { isPending, data, error } = useQuery({
    queryKey: ["user"],
    queryFn: fetchDummyData,
  });

마무리

와 근데 공부하면서 버전이 바껴서 그런지 하나도 기억이 안 나서 당황스러웠다
글 쓰길 잘 했다 ^_^,,,프로젝트에 쓸 때 더 빠르게 적용이 가능할 것 같다

profile
프론트엔드 개발 블로그

0개의 댓글