티스토리 뷰

프론트엔드를 접해보신 분들은 누구나 다음과 같은 고민을 해보신 적 있을겁니다.

상태관리

여기서 관리 대상인 상태란 무엇일까요? 개인적으로 고민했을 때에는 언제든지 변경될 수 있는 데이터를 '상태'라고 일컫는 것 같아요. 변경의 여지가 있으니 관리를 해 주어야 하는 데이터가 되니까요.

그럼 여기서 프론트엔드적 측면에서 관리해야하는 데이터는 크게 두가지가 있습니다. 서버 데이터와 클라이언트 데이터.

서버에서 받는 데이터의 특징

  1. 클라이언트와 다른 공간에서 관리되어짐
  2. get/update 과정에서 비동기 API가 필요함
  3. 불특정 다수와 공유되는 데이터로 사용자가 의도하지 않은 변경들이 일어날 수 있음

클라이언트에서 받는 데이터의 특징

  1. 클라이언트 소유의 공간에서 관리되어짐
  2. 비동기적 API가 필요하지 않음
  3. 다른 사람과 공유되지 않으며, 사용자 흐름에 따라 상태 변경이 가능함 고로 최신 상태의 데이터 유지 가능

(물론 더 다양한 특징들이 존재합니다.)

그럼 이제 심화단계로 나아가 우리의 많은 프론트엔드 선배들은 다음과 같은 고민을 하게 됩니다.

각각의 특징이 다르다면
서버와 클라이언트에서 받는 상태 관리를 나누어서 해주면 좋지 않을까?

이렇게 해서 우리곁에 등장한 것이 바로 리액트쿼리 (react query)입니다. 한 마디로 말하면 리액트 쿼리는 서버 상태관리를 위해 탄생한 것이죠. 아! 이름에서 느껴지듯 리액트 쿼리는 리액트를 위한 서버상태관리 라이브러리입니다.

https://react-query.tanstack.com/

 

React Query

Hooks for fetching, caching and updating asynchronous data in React

react-query.tanstack.com

 

 

리액트쿼리 공식홈페이지 첫 메인에 적혀있는 말.

Performant and powerful datasynchronization for React

Fetch, cache and update data in your React and React Native applications all without touching any "global state".

리액트를 위한 강력하고 성능 좋은 데이터 동기화. 전역 상태를 건드리지 않고, 데이터를 가져오고 캐시/업데이트를 진행합니다.

대체 얼마나 좋길래 저렇게 자부심이 있을까? 하는 생각에 간단하게 도큐멘트를 읽어보고 장점을 정리해보았어요. 다만, 정말 리액트쿼리를 처음 접한 제가 공부용으로 체크해둔것이기 때문에 심화를 원하시는 분은 최고의 선생님. 공식 홈페이지를 참고하시길 추천드립니다-!

리액트쿼리 장점

  1. 서버 상태
    read한 데이터를 수정하여, update를 수행하면 자동으로 업데이트를 반영하고 최신 데이터를 read한다.
  2. 캐싱
    데이터가 오래되었을 시, 자동으로 데이터를 가지고 온다. (주기는 사용자 설정 가능)
  3. 동기화
    당연한 말이겠지만 1번과 2번의 이유로 서버의 데이터와 항상 동기화 되어있다.
  4. zero config
    별도의 구성이 없이도 정상동작하지만 사용자의 편의에 따라 config 커스텀 또한 가능하다.
    * 참고사항 : 쿼리에서 캐시된 데이터는 언제나 과거 데이터 취급 -> 데이터가 뿌려진 브라우저에 포커싱 하였는데, 오래된 데이터로 취급 시, refresh 발생 (ex. 브라우저 tab 이동) -> 비활성화 된 쿼리들은 GC(가비지 컬렉터)에 의해 처리 -> 쿼리 실패 시, 3번까지 재시도
  5. 직관적인 api 호출 코드
    promise, await, async와 비슷한 방식 사용하기 때문에 더욱 이해하기 쉽다.
  6. 원활한 디버깅

결론적으로 저 모든 특징을 활용하여 서버 상태관리를 진행한다면 클라이언트에서는 필요한 상태에 대하여만 관리가 가능하다.

다음은 리액트쿼리 공식 홈페이지에 있는 예시 코드이다.

https://codesandbox.io/s/github/tannerlinsley/react-query/tree/master/examples/simple

 

tannerlinsley/react-query - CodeSandbox

tannerlinsley/react-query using axios, react, react-dom, react-query, react-scripts, stop-runaway-react-effects, styled-components

codesandbox.io

/* eslint-disable jsx-a11y/anchor-is-valid */
import React from "react";
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider, useQuery } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
import axios from "axios";

const queryClient = new QueryClient();

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Example />
    </QueryClientProvider>
  );
}

function Example() {
  const { isLoading, error, data, isFetching } = useQuery("repoData", () =>
    axios.get(
      "https://api.github.com/repos/tannerlinsley/react-query"
    ).then((res) => res.data)
  );

  if (isLoading) return "Loading...";

  if (error) return "An error has occurred: " + error.message;

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{" "}
      <strong>✨ {data.stargazers_count}</strong>{" "}
      <strong>🍴 {data.forks_count}</strong>
      <div>{isFetching ? "Updating..." : ""}</div>
      <ReactQueryDevtools initialIsOpen />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

사용 방법은 리액트를 접해본 사람에게는 크게 어렵지 않을것이라고 생각한다. 리액트 훅을 사용하는 방법과 동일하기 때문이다.

먼저 리액트 쿼리에서 필요한 기능을 import한다. 다음은 기본중의 기본 사용이고, 앞으로 익숙해지면 더 많은 기능을 불러와서 사용하면 된다.

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

쿼리의 사용을 선언한 후,

 const queryClient = new QueryClient()

그리고 부모 컴포넌트를 QueryClientProvider로 감싸준다. 해당 뜻을 잘 모르겠는 사람은 react provider 공부를 추천한다. 간단하게 말하면 부모 컴포넌트에서 전달해주는 값들을 자식 컴포넌트들에서 모두 받겠다는 의미이다.

<QueryClientProvider client={queryClient}>
	<Example />
</QueryClientProvider>

이제 useQuery를 사용하여 서버 데이터를 받아온다. 사용은 일반 훅과 동일한데, 다음과 같이 사용하면 된다.

useQuery(queryKey, queryFn);

queryKey라는 것은 useQuery의 고유key라고 생각하면 되는데, 이를 기반으로 데이터 캐싱을 관리하게 된다. 예제처럼 단순 문자열을 사용해도 되고, 배열을 사용해도 된다. 더불어 배열 사용 시, 순서의 다름을 인정하기 때문에 [1, 2]의 쿼리키와 [2, 1]의 쿼리키는 서로 다른 키로 인식한다.

다음은 서버의 데이터를 가져오는 함수를 작성하여주면 된다. 이는 일반 함수 사용도 되고, 화살표 함수 사용도 되니 편의에 따라 사용하면 되지만 개인적으로는 화살표 함수에 한 표-!

const { isLoading, error, data } = useQuery('repoData', () =>
 fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
   res.json()
 )
)

또한 쿼리가 변수에 의존하는 경우, queryKey에 선언해 줘야 한다. 바로 다음과 같은 형식으로 말이다.

const { isLoading, error, data } = useQuery(['repoData', id], () =>
 fetch(`https://api.github.com/repos/tannerlinsley/react-query/${id}`).then(res =>
   res.json()
 )
)

 

리액트쿼리가 무엇인지 맛보기 위하여 가장 기본적인 코드를 톺아보았는데, 사실 더 깊고 넓은 코드들이 많을 것이다. 아무튼 리액트쿼리란 이런것이(라고한)다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함