React Query 맛보기

김범현·2022년 11월 10일
0

채용글에도 제법 보이고, 얼마전 면접을 볼 때도 react-query에 대해서 아는지 질문이 들어왔다.
어...react-swr은 예전에 본적이 있는 것 같긴 한데 뭐지?

결론을 위로 당겨써보자면, react query 를 사용하면 아래와 같은 장점이 있다.
1. 나는 이 때 새로 패치하겠어! 라고 선언적으로 프로그래밍 할 수 있기 때문에 코드가 간결해진다.
리덕스를...써보진 않았지만 기본적으로도 작성해야할 코드가 많은데 비동기 작업을 하려면 리덕스 사가나 썽크와 같은 라이브러리도 사용해야 하기 때문에 코드가 더 길어진다.
2. 원하는 시점에 서버의 상태를 업데이트 할 수 있다. (인터벌, 포커싱 될 때 등등)

그렇다고 react-query 만으로도 상태관리가 가능하냐? 하면 그건 아니다.
이 라이브러리는 서버에서 받아오는 데이터만을 다루기 때문에 전역 상태 관리는 따로 해야 한다.
대신 그 양이 줄어들기 때문에 가벼운 상태 관리 라이브러리를 사용해 볼 수는 있겠다.

React Query

React Query는 서버로부터 데이터를 가져오고, 그 데이터를 캐싱, 에러 핸들링 등 비동기 작업을 수월하게 할 수 있도록 도와주는 라이브러리이다.

먼저 React Query는 여느 라이브러리와 마찬가지로 최상단에서 프로바이더를 통해 무언가를 주입을 하고 시작한다.

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

const queryClinet = new QueryClient();

<QueryClientProvider client={queryClinet}>
  <App />
  </QueryClientProvider>

그 다음 사용법을 보도록 하자.
먼저 useQuery다.

const result = useQuery(, 함수, 옵션);

첫번째 인자로 들어가는 키는 어플리케이션 전체에서 쿼리를 다시 가져오고, 캐싱하고, 공유하는데 내부적으로 사용된다.
두번째 인자로 들어가는 통신을 위한 함수로 프로미스를 반환한다.
옵션들에는 이런 것들이 있다.

refetchInterval: 지정한 시간 간격에 따라 데이터를 패칭
refetchOnWindowFocus: 브라우저에 포커싱 될 때마다 새로운 데이터 패칭
onSuccess: 패칭 성공
onError: 패칭 실패

result 에는 아주 다양한 상태들이 포함되어 있고 기본적인 상태는 아래와 같다.

isLoading: 아직 데이터를 받아오지 못함.
isError: 에러가 발생함.
isSuccess: 데이터를 받아옴.

아래는 간단하게 테스트해본 코드이다.
path만 나와있는건 무시하자. axios baseurl 설정을 해놔서 그렇다.

  const { data, isLoading, isError } = useQuery("getPosts", async () => {
    const { data } = await axios.get("/post");
    return data;
  });

  if(isLoading) {
    return <h2>Loading...</h2>
  }

  if(isError) {
    return <h2>{error.message}</h2>
  }

  return (
    <>
      { data?.map(({ id, title }) => (
        <div key={id}>{title}</div>
      )) }
    </>
  );

그 다음은 useMutation이다. 이 훅은 POST, PUT, DELETE 요청을 할 때 사용을 한다.

const { mutate } = useMutation(함수, 옵션);

함수의 역할은 useQuery와 같고, mutate함수를 통해 api 호출 함수를 실행할 수 있다.
옵션에서는 뮤테이션의 진행상황에 따른 콜백함수를 작성할 수 있다. 보통 뮤테이션 성공 후 캐시를 초기화할 때 사용할 수 있다.
어...? 이거 완전 아폴로랑 비슷...

  const { mutate } = useMutation(value => {
    return axios.post("/post", value)
  }, {
  	onSuccess: (data, variables) => {
      // 작업에 성공하면 getPosts에 매핑된 useQuery api 함수를 실행한다.
      queryClient.invalidateQueries("getPosts");
      // 만약 muation 에서 리턴된 값을 이용해 get 을 해야 하는 경우에는 setQueryData를 사용한다.
      queryClient.setQueryData(["getPosts", { id: 5 }], data);
    }
  })

  return (
    <>
      <button onClick={handleClick}>버튼</button>
    </>
  );
profile
프론트엔드 개발자 입니다.

0개의 댓글