-
[React] React Query와 React Suspense 사용하기JavaScript/React 2023. 3. 28. 17:52728x90반응형
React Query를 알아보자
캡스톤을 진행하던 중에 리액트 쿼리에 대해 공부하게 되었어요. 아직 디자인이 안나와서 본격적인 개발하기 전이라 필요한 공부를 하고 있어요. 아무튼아무튼 리액트 쿼리에 대해서 알아보자구요 🧐
🍊 React-query 이해하기
쿼리(query)를 이용하면 promise 기반 메소드(get, post 등)와 함께 사용하여 서버에서 데이터를 가져올 수 있습니다. 서버의 데이터를 수정할 경우는 mutation을 사용하도록 합니다.
설치하기
$ npm i @tanstack/react-query # or $ pnpm add @tanstack/react-query # or $ yarn add @tanstack/react-query
먼저 react-qeury를 설치해주고 아래처럼 설정해줍니다.
// src/index.js import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import { QueryClient, QueryClientProvider } from "react-query"; import { ReactQueryDevtools } from "react-query/devtools"; const queryClient = new QueryClient(); ReactDOM.render( <React.StrictMode> <QueryClientProvider client={queryClient}> {/* devtools */} <ReactQueryDevtools initialIsOpen={true} /> <App /> </QueryClientProvider> </React.StrictMode>, document.getElementById("root") );
🍊 useQuery
useQuery는 데이터를 get하기 위한 api입니다.
📍 useQuery의 구성요소
- unique한 key
- 데이터(혹은 에러)를 반환하는 함수
import { useQuery } from 'react-query' function App() { const result = useQuery('todos', fetchTodoList) }
위 코드에서 useQuery에서 반환한 결과 result에는 query에 대한 모든 정보(템플릿 작성, 데이터 사용 등)가 포함되어 있습니다.
📍 result가 가지는 상태
- isLoading 혹은 status === 'loading'
- 의미: 데이터가 존재하지 않음, 데이터를 가져오는 중
- isError 혹은 status === 'error'
- 의미: 쿼리 오류 발생
- isSuccess 혹은 status === 'success'
- 의미: 쿼리 성공, 데이터를 가져올 수 있는 상태
- isIdle 혹은 status === 'idle'
- 의미: 쿼리가 비활성화 되어있음
- error : 쿼리가 isError 상태일 때, 에러는 error 속성을 통해 접근 가능
- data : 쿼리가 success 상태일 때, 데이터는 data 속성을 통해 접근 가능
- isFetching : 백그라운드 refetching을 포함해서 쿼리가 fetching 상태일 경우, isFetching 값은 항상 true
🍊 useQuery 사용하기
일반적으로 isLoading 상태를 확인한 후에 isError 상태를 확인해서 데이터 사용 가능 여부를 판단합니다.
function Todos() { const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList) if (isLoading) { return <span>Loading...</span> } if (isError) { return <span>Error: {error.message}</span> } // We can assume by this point that `isSuccess === true` return ( <ul> {data.map(todo => ( <li key={todo.id}>{todo.title}</li> ))} </ul> ) }
status를 사용하면 위 방법보다 더 간단하게 사용할 수도 있습니다.
function Todos() { const { status, data, error } = useQuery('todos', fetchTodoList) if (status === 'loading') { return <span>Loading...</span> } if (status === 'error') { return <span>Error: {error.message}</span> } // also status === 'success', but "else" logic works, too return ( <ul> {data.map(todo => ( <li key={todo.id}>{todo.title}</li> ))} </ul> ) }
useQueries
useQuery를 여러 개 사용할 경우는 useQueries를 사용합니다.
🍊 Mutation
mutation은 서버에 데이터를 업데이트 하도록 서버에 네트워크 호출을 실시합니다.
이를 위해 React Query는 'useMutation' hook 을 export 합니다.
CRUD(Create, Read, Update, Delete)에서 useQuery가 C를 맡았다면, useMutation은 RUD를 담당합니다.
useMutation 사용하기
로그인 예시입니다.
import { useState, useContext, useEffect } from "react"; import loginApi from "api"; import { useMutation } from "react-query"; const Index = () => { const [id, setId] = useState(""); const [password, setPassword] = useState(""); const loginMutation = useMutation(loginApi, { onMutate: variable => { console.log("onMutate", variable); // variable : {loginId: 'xxx', password; 'xxx'} }, onError: (error, variable, context) => { // error }, onSuccess: (data, variables, context) => { console.log("success", data, variables, context); }, onSettled: () => { console.log("end"); } }); const handleSubmit = () => { loginMutation.mutate({ loginId: id, password }); }; return ( <div> {loginMutation.isSuccess ? "success" : "pending"} {loginMutation.isError ? "error" : "pending"} <input type="text" value={id} onChange={e => setId(e.target.value)} /> <input type="password" value={password} onChange={e => setPassword(e.target.value)} /> <button onClick={handleSubmit}>로그인</button> </div> ); }; export default Index;
📍 mutation이 가지는 상태
- isIdle 혹은 status === 'idle'
- 의미: muation이 현재 비활성화 상태이거나 fresh/reset 상태임
- isLoading 혹은 status === 'loading'
- 의미: mutation이 현재 실행 중
- isError 혹은 status === 'error'
- 의미: mutation에 오류 발생
- isSuccess 혹은 status === 'success'
- 의미: mutation이 성공했고 mutation 데이터를 사용할 수 있는 상태
- error : mutation이 error 상태일 때, 해당 에러는 error 속성을 통해 접근 가능
- data : mutation이 success 상태일 때, 해당 데이터는 data 속성을 통해 접근 가능
🍊 react Suspense 사용하기
Suspense란?
Suspense는 아직 렌더링이 준비되지 않은 컴포넌트가 있을때 로딩 화면을 보여주고 로딩이 완료되면 해당 컴포넌트를 보여주는 React에 내장되어 있는 기능입니다. 이제 react-query와 함께 사용해볼겁니다.
예시
const { data } = useQurey("test", testApi, { suspense: true }); return ( <Suspense fallback={<div>loading</div>}> <ErrorBoundary fallback={<div>에러 발생</div>}> <div>{data}</div> </ErrorBoundary> </Supense> );
위 코드에서 isLoading이 true일 경우에는 Suspense의 fallback 내부 컴포넌트가 보여지고,
isError가 true일 경우에는 ErrorBoundary의 fallback 내부 컴포넌트가 보여집니다.
참고
https://tanstack.com/query/latest/docs/react/guides/important-defaults
https://ko.reactjs.org/docs/react-api.html#reactsuspense
https://www.daleseo.com/react-suspense/
LIST'JavaScript > React' 카테고리의 다른 글
[React] 슬라이드형 뷰어 구현하기 (MobileStepper와 SwipeableViews) _MUI (0) 2023.04.06 [React] 리액트 생명주기 메서드 LifeCycle Method (0) 2023.03.29 [React] 상태 관리 라이브러리 Recoil 이해하기 (0) 2023.03.27 [ReactJS] 리액트에서 Apollo Client로 전역 상태 관리하기 (0) 2023.02.01 [ReactJS] React Hook Form 사용하기 (0) 2023.01.30