[React] React-Query - 겉핥기

2022. 11. 18. 12:28·React/실험실
반응형

들어가며

지난번 React-Query에 대한 필요성을 간략하게 알아봤다. 

이번에는 React-Query 자체에 대해서 정리를 해보려고 한다.

 

React-Query ? 

서버에서 값을 가져오거나, 캐싱, 값 업데이트, 에러 핸들링 등 비동기 과정을 사용할 때 

도움을 준다. 

 

기존 Redux, Mobx, Recoil 같은 상태 관리 라이브러리가 있지만, 서버 데이터와 클라이언트

데이터를 분리시킬 수 있다는 장점이 있다. 

 

React-Query의 장점

▶ 서버의 상태 업데이트, 데이터 패칭, 캐싱 등을 쉽게 할 수 있도록 도와준다.

 

▶ Redux 등, 전역 상태 관리를 통해서 서버의 데이터를 비동기로 가져오기 위해서는 
     추가적으로 작성해야하는 코드 많지만 React-Query는 간단하게 처리해준다. 

 

▶  코드가 간단해진다는 것은 유지 보수를 쉽게할 수 있다는 뜻이 된다.

 

▶  같은 데이터를 여러번 요청할 경우 중복을 제거해준다.

 

▶  백그라운드에서 자동으로 데이터를 업데이트시켜준다.

이 외에도 많지만 이것은 좀 더 React-Query와 친해지고 더 공부해보자! 

 

React-Query의 라이프사이클

React Query는 5단계로 라이프 사이클이 구성되어 있다. 

▶ Fetching : 데이터를 요청한 상태 

 

▶  Fresh : 데이터가 만료되지 않은 상태 
    ▷ 컴포넌트의 상태가 변경되어도 데이터를 다시 요청하지 않는다. 

    ▷ 새로고침을 하면 다시 Fetching 한다. 

 

▶ Stale : 데이터가 만료된 상태 

    ▷ 서버에서 데이터를 받는 사이에 다른 유저가 데이터를 추가, 수정, 삭제등을 해서 최신화가
        필요한 상태를 말한다. 

    ▷ 컴포넌트가 마운트, 업데이트되면 다시 데이터를 요청한다. 

    ▷ Fresh 상태에서 Stale 상태로 변경되는데 걸리는 시간이 StaleTime이다

 

▶ Inactive : 사용하지 않는 상태

    ▷ 일정 시간이 지나면 가비지 콜렉터가 캐시에서 제거한다. 

    ▷ 기본값은 5분이다. 

    ▷ Inactive 상태에서 캐싱된 상태로 남아있는 시간을 CacheTime이라고 한다. 

 

▶ Delete : 가비지 콜렉터에 의해 캐시에서 제거된 상태 

환경 설정 

npx react-create-app client

cd client 
npm install react-query

프론트 환경에서는 CRA를 사용해서 간단하게 만들고 react-query를 설치했다. 

 

express server

서버 환경은 express 를 사용해서 간단하게 구성했다.

 

백엔드 준비

// routes/index.js 

var express = require("express");
var router = express.Router();

const dummyList = [
  { title: "title1", contents: "text1", isFinish: false },
  { title: "title2", contents: "text2", isFinish: false },
  { title: "title3", contents: "text3", isFinish: true },
  { title: "title4", contents: "text4", isFinish: true },
  { title: "title5", contents: "text5", isFinish: false },
  { title: "title6", contents: "text6", isFinish: false },
];

/* GET home page. */
router.get("/api", function (req, res, next) {
  // console.log(dummyList);
  res.status(202).json(dummyList);
});

router.post("/api", function (req, res, next) {
  dummyList.push(req.body);

  res.status(201);
});

module.exports = router;

간단하게 " /api " 경로로 get 요청하면 dummyList 데이터를 넘겨주는 API이다.

post 요청의 경우 업데이트를 해주고 있다. 

 

프론트엔드 설정하기

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

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

const queryClient = new QueryClient();

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </React.StrictMode>
);

QueryClient를 사용해서 client를 먼저 만들어줬습니다. 

여기서 다양한 옵션을 설정할 수 있는데, 이것도 모두 공부하고 지나가면 좋겠지만 

분량이 많아질 것 같아서 다음에 공부하자..! ( 점점 할게 많아지는.... )

 

useQuery

import "./App.css";
import { useQuery } from "react-query";
import axios from "axios";

const getTodos = async () => {
  const { data } = await axios.get("/api");

  return data;
};

function App() {
  const query = useQuery("todos", getTodos);
  console.log(query);

  return (
    <div className="App">
      {query.data.map((data) => {
        return <div key={data.title}>{data.title}</div>;
      })}
    </div>
  );
}

export default App;

useQuery를 사용해서 데이터를 요청할 수 있다. 

query 안에는 data, isLoading, isSuccess, isError 등 많은 정보를 가지고 있다. 

 

만약 Redux였다면 직접 구현해야하는 부분을 React-Query는 알아서 제공을 해주고 있다. 

API 요청이 완료되기 전에는 status 상태가 loading인데, 완료되면 success or failed로 나뉜다. 

 

실제 결과 데이터는 data에 들어가있다. 

 

useMutation

import "./App.css";
import { useMutation, useQuery } from "react-query";
import axios from "axios";

const getTodos = async () => {
  const { data } = await axios.get("/api");

  return data;
};

const postTodos = (data) => {
  axios.post("/api", data);
};

function App() {
  const query = useQuery("todos", getTodos);
  const mutation = useMutation(postTodos, {
    onSuccess: () => {
      console.log("Update Todos");
    },
  });

  const handleButtonClick = () => {
    mutation.mutate({ title: "title7", contents: "text7", isFinish: false });
  };

  return (
    <div className="App">
      {query.status === "success" &&
        query.data.map((data) => {
          return <div key={data.title}>{data.title}</div>;
        })}

      <button onClick={handleButtonClick}>버튼</button>
    </div>
  );
}

export default App;

useMutation을 사용해서 데이터를 업데이트할 수 있다. 

이때, 데이터를 추가하고 추가한 값은 실시간으로 업데이트 되고 있지 않다. 

 

이것을 useMutation은 get을 한번 더 하는 방법과 기존 값을 업데이트하는 방법 2개를 선택할 수 있다. 

 

한번 더 요청하기

function App() {
  const queryClient = useQueryClient();
  
  const query = useQuery("todos", getTodos);

  const mutation = useMutation(postTodos, {
    onSuccess: () => {
      queryClient.invalidateQueries("todos");
    },
  });
  
  // ...
}

useQueryClient를 사용하면 client에 접근할 수 있게 되는데, invalidateQueries는 

기존 데이터를 무효화하고 다시 가져올 수 있게 해주는 함수이다. 

 

키값 배열을 넣을 수 있고, 혹은 키값 하나만 넣을 수 있다. 

여기서 사용하는 키는 useQuery를 사용할 때 첫 번째 매개변수이다. 

 

기존 값 업데이트하기 

 const mutation = useMutation(postTodos, {
    onMutate: (data) => {
      const previousValue = queryClient.getQueryData("todos");
      console.log("previousValue", data);

      queryClient.setQueryData("todos", (old) => {
        console.log("old", old);
        return [...old, data];
      });

      return previousValue;
    },
    onSuccess: (result, variables, context) => {
      console.log("성공 메시지:", result);
      console.log("변수", variables);
      console.log("onMutate에서 넘어온 값", context);
    },
  });

서버에 다시 요청하는 방법은 간단하지만 결국 서버의 리소스를 사용하는 것이라 꺼려지게 된다. 

그래서 기존 값을 업데이트 하는 경우가 있을 텐데, React Query에서는 그나마 간단하게 가능하다. 

 

queryClient의 getQueryData는 요청했던 데이터를 가져올 수 있고, 

setQueryData는 해당 키의 데이터를 수정할 수 있다.

그리고 data는 mutation을 통해 넘긴 데이터를 가져올 수 있다. 

 

이것을 활용해서 서버에 직접 요청을 할 필요없이 데이터를 업데이트할 수 있다. 

 

이번에는 정말 간단하게 React-Query에 대해서 알아봤다. 

한번에 최대한 많은 내용을 담는 것도 좋겠지만 큰 틀을 이해하고 하나씩 공부하는 것도 좋다고 생각해서

이번에 부족했던 부분은 다시 공부해서 작성하겠다. 

반응형
저작자표시 비영리 변경금지 (새창열림)

'React > 실험실' 카테고리의 다른 글

[React] React-Query - QueryClient stale & cacheTime  (0) 2022.11.22
[React] React-Query - 로그인 유지하기  (0) 2022.11.21
[React] 벨로퍼트와 함께하는 React Testing - 자바스크립트 테스팅 기초  (0) 2022.11.17
[React] 벨로퍼트와 함께하는 React Testing - 개요  (0) 2022.11.16
[React] Test Coverage  (0) 2022.11.15
'React/실험실' 카테고리의 다른 글
  • [React] React-Query - QueryClient stale & cacheTime
  • [React] React-Query - 로그인 유지하기
  • [React] 벨로퍼트와 함께하는 React Testing - 자바스크립트 테스팅 기초
  • [React] 벨로퍼트와 함께하는 React Testing - 개요
잉여개발자
잉여개발자
풀스택 개발자를 목표로 잉여롭게 개발 공부도 하면서 다양한 취미 생활도 즐기고 있는 잉여 개발자입니다.
  • 잉여개발자
    잉여로운 개발일지
    잉여개발자
    • 분류 전체보기 (789)
      • 개발정보 (36)
      • 개발환경 (7)
      • 개발생활 (19)
      • React (141)
        • 이론 (23)
        • 기능 (12)
        • 실험실 (88)
        • 버그 (6)
        • 패스트캠퍼스 (9)
        • Npm (3)
      • React Native (28)
        • 공통 (6)
        • TypeScript (3)
        • JavaScript (18)
        • 버그 (1)
      • Next.js (30)
        • 이론 (13)
        • 실험실 (13)
        • 버그 (3)
      • Web (35)
      • 알고리즘 (202)
        • 풀이 힌트 (39)
      • JavaScript (47)
      • TypeScript (29)
        • 기초 (27)
        • 실험실 (2)
      • Node.js (13)
        • 이론 (0)
        • 기능 (3)
        • 실험실 (9)
        • 버그 (1)
      • 도커 (4)
      • CCNA (22)
        • 이론 (4)
        • 문제 (18)
      • 취미생활 (167)
        • 잉여로운 칵테일 (2)
        • 잉여의 식물키우기 (130)
        • 잉여로운 여행기 (11)
        • 잉여의 제2외국어 (21)
        • 잉여로운 책장 (2)
      • Java (1)
        • Java의 정석 (1)
      • 꿀팁 공유 (3)
  • 태그

    덤프
    바질 키우기
    식물
    CSS
    영어회화
    react
    프로그래머스
    네트워크
    javascript
    CCNA
    redux
    typescript
    네이버 부스트캠프
    타일러영어
    바질
    ReactNative
    영어독학
    알고리즘
    다이소
    webpack
    리액트
    리얼클래스
    Node.js
    ChatGPT
    next.js
    Babel
    타입스크립트
    리얼학습일기
    자바스크립트
    Docker
  • hELLO· Designed By정상우.v4.10.1
잉여개발자
[React] React-Query - 겉핥기
상단으로

티스토리툴바