본문 바로가기

Front-End: Web/React.js

[코딩애플] react-query 사용하여 실시간 데이터 가져오기

반응형

react-query 설명 및 설치

react-query란?

  • ajax 성공시/실패시 html 보여주려면?
  • 몇초마다 자동으로 ajax 요청하려면?
  • 실패 시 몇초 후 요청을 재시도 하려면?
  • prefetch? (다음 페이지를 미리 가져오려면?)

다음과 같은 것들을 고려하여 코드를 짤 수도 있겠지만 만약 이게 귀찮다! 하면 react-query 라이브러리를 이용하자. react-query를 사용하면 위의 것들을 쉽게 구현할 수 있다.

어디에 사용할까?

하지만 항상 유용한 건 아니다.

실시간 SNS라던지, 코인 거래소처럼 **실시간으로 데이터를 계속 가져와야하는 사이트에 쓰면 굿**이다. 대부분 사이트들은 실시간 데이터를 가져올 필요는 없으므로 알아서 판단하고 필요에 따라 라이브러리를 사용하자.

설치하기

  1. 다음 명령어를 입력하여 라이브러리를 설치한다. (라이브러리 이름이 react-query에서 @tanstack/react-query로 변경되었다)
npm install @tanstack/react-query
  1. index.js에서 react-query를 세팅을 한다.

🕹️index.js

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

const queryClient = new QueryClient();

root.render(
    <QueryClientProvider client={queryClient}>
        ...
    </QueryClientProvider>)

직접 사용해보기

기능을 만들어보자. 목표는 해당 url에 접근하여 서버에서 유저이름을 가져와 보여주는 거다.

https://codingapple1.github.io/userdata.json

🕹️App.js

axios 요청을 하자.

function App(){
    ...
	axios.get('https://codingapple1.github.io/userdata.json').then((a) => {
        a.data // 여기에 데이터가 있을 것
    })
    ...
}

이렇게 대신 react-query를 이용해서 ajax를 요청해보자.

import { useQuery } from '@tanstack/react-query';

function App() {
    ...
    let result = useQuery(['작명'], () => 
        axios.get('https://codingapple1.github.io/userdata.json').then((a) => {
        	return a.data
    	})
    )
    ...
}
  • array로 작명을 작성해준다.
  • 가져온 데이터를 return 해준다.

장점

ajax 성공/실패/로딩중 쉽게 파악 가능

result.data

데이터 가져오기 성공 시 가져온 데이터가 담겨있음.

result.isLoading

로딩중인지 유무를 알 수 있음. return 값은 boolean.

result.error

데이터 가져오기가 실패했는지 알려줌. return값은 boolean.

Q. 로딩중일 때 '로딩중입니다' 를 보여주고 싶으면?

function App(){
    ...
	return(
        <>
        	{result.isLoading ? '로딩중' : result.data.name}
        </>
	)
}

혹은 이렇게도 작성 가능하다.

function App(){
    ...
	return(
        <>
        	{result.isLoading && '로딩중'}
   			{result.error && '에러남'}
			{result.data && result.data.name}
        </>
	)
}

쌩 리액트로 이걸 구현하려면 state를 오지게 만들어야 한다. isLoadindg, data, ... 근데 react-query를 사용하면 state를 만들 필요 없이 간편하게 데이터를 가져오고 쉽게 UI를 구현할 수 있다.

틈만나면 알아서 자동으로 ajax 재요청해줌

then 안에 콘솔을 찍어보자. 그럼 ajax 요청일 될 때마다 콘솔이 찍힐거다.

그리고 다른 프로그램을 띄웠다가 다시 오거나, 다른 탭을 생성해서 다른 탭에 갔다가 다시 돌아오면 ajax 콘솔이 찍힌다. 이처럼 자동으로 refetch를 해준다.

실시간으로 신선한 데이터를 보여주어야하는 실시간 sns, 코인 거래소 같은 곳에선 걱정안해도 된다. 얘가 다 알아서 해주니까~

refetch 간격 설정하기

어쨌든 이렇게 자동으로 ajax를 재요청해주는 것을 refetch라고 하는데 이 기간이 너무 잦다! 싶으면 간격을 설정할 수도 있다.

let result = useQuery(['작명'], () => {
    ...
	},
    { staleTime : 2000 }
)

나는 refetch 기능이 필요없다! 하면 refetch를 끄는 기능도 있다.

실패시 재시도(retry) 알아서 해줌

ajax 요청을 실패하면 자기가 알아서 ajax 시도를 다시 여러번 해준다.

state 공유 안해도 된다

만약 자식 컴포넌트에서 유저이름을 똑같이 보고 싶다고 하면, state에 저장해놨다가 하위 컴포넌트로 props로 전송해주어야 한다.

근데 이게 싫다! 귀찮다! 하면 **하위 컴포넌트인 자식 컴포넌트에서 바로 useQuery로 감싸서 ajax 요청하는 코드를 똑같이 작성**하면 된다.

그러면 상위에서도 하위 컴포넌트에서도 똑같은 ajax 요청을 두 번이나 하니까 비효율적인데? 라고 생각할 수 있는데, react-query는 똑똑해서 똑같은 곳으로 요청을 두 번이나 하지 않는다. 합쳐서 한 번만 처리를 해준다. 그래서 state나 props 전송 같은 게 필요없고 그냥 ajax 요청하는 코드를 한 번 더 작성해주기만 하면 된다.

ajax 결과 캐싱 기능

react-query는 캐싱 기능이 있다.

캐싱이란 ajax 성공 결과를 5분동안 얘가 기억을 해둔다는 거다. 그래서 같은 경로로 ajax를 요청하는 코드가 또 실행이 된다면,

  1. 12:10 userdata.json GET 요청
  2. 12:13 userdata.json GET 요청

➡️ react-query가 12:10 결과를 우선적으로 보여줌 (기존 결과물을 먼저 보여줌)

그래서 유저는 더 빠르게 결과물을 보게 된다고 느끼게 된다.

Recap

실시간으로 데이터를 보여주는 사이트면 react-query를 설치해서 사용하면 편리하다. 그게 아니라면 쓸모는 없다.

추가로 redux-toolkit을 설치했다면 RTK Query도 자동설치된다. 이건 방금 배운거랑 유사한데 문법이 더러우니까 react-query 사용하는 게 더 낫다.

반응형