리액트 쿼리를 공부해보자!

이상진·2023년 5월 29일
1

React

목록 보기
4/6
post-thumbnail

글을 작성하며

내가 리액트 쿼리를 공부하는 이유는 두 번째 스터디 주제이기 때문이다.
나는 리액트 쿼리를 아주 살짝 공부 했었다. (코딩애플 선생님 강의)
예전에 공부했을때 리액트 쿼리를 쓰는 이유는 실시간으로 변화하는 값을 빠르게 관리하기 위한 역할을 해준다고 기억하고있다.
이제 본론으로 들어가 리액트 쿼리에 대해 정확하게 공부해보자!

Reacty-Query

React Query는 React 애플리케이션에서 효율적인 데이터 요청, 캐싱, 상태 관리 등을 단순화하여 개발자가 비동기 작업을 간편하게 처리할 수 있도록 도와주는 라이브러리이다.

리액트 쿼리를 사용하는 이유

  1. 간편한 데이터 관리: React Query는 API 호출과 데이터 상태 관리를 간편하게 처리할 수 있다. 데이터 요청을 훨씬 쉽게 작성하고, 데이터 업데이트 및 캐싱을 자동으로 처리한다.
  2. 성능 최적화: React Query는 캐싱과 데이터 재사용을 통해 애플리케이션의 성능을 향상시킨다.
  3. 유연한 구성 옵션: React Query는 다양한 구성 옵션을 제공하여 개발자가 필요에 맞게 설정할 수 있다.
  4. 서버와의 통신 추상화: React Query는 서버와의 통신을 추상화하여 개발자가 비동기 작업을 간단하게 처리할 수 있도록 한다.
// 리액트 쿼리 초기 세팅

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}>
      <ReactQueryDevtools initialIsOpen={true} />
      <App />
    </QueryClientProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

useQuery

  1. useQuery 는 비동기로 작동한다.
  2. 데이터를 get 하기 위한 api
  3. 첫번째 파라미터로 unique Key가 들어가고, 두번째 파라미터로 비동기 함수가 들어간다.
  4. return 값은 api의 성공, 실패의 여부를 나타낸다.
import { useQuery } from 'react-query';

const UsersList = () => {
  const { data, isLoading, isError } = useQuery('users', fetchUsers);

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

  if (isError) {
    return <div>Error occurred while fetching users.</div>;
  }

  return (
    <div>
      <h1>User List</h1>
      <ul>
        {data.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

const fetchUsers = async () => {
  const response = await fetch('https://api.example.com/users');
  const data = await response.json();
  return data;
};

위의 예제에서는 useQuery를 사용하여 users라는 키로 데이터를 가져오고 관리한다.
fetchUsers라는 비동기 함수를 통해 실제 데이터를 가져오는 작업을 수행한다.
useQuery 훅은 data, isLoading, isError와 같은 상태를 반환하여 데이터 로딩 상태와 오류 상태를 처리할 수 있다.

useQueries

useQuery 를 사용하기 귀찮을때 사용할 수 있다.

useQueries는 promise.all처럼 useQuery를 하나로 묶을 수 있는다. promise.all과 마찬가지로 하나의 배열에 각 쿼리에 대한 상태 값이 객체로 들어온다.

// useQueries 를 이용하여 세 가지 쿼리들을 동시에 처리하는 예제 

import { useQueries } from 'react-query';

const UsersList = () => {
  const queryConfig = [
    {
      queryKey: 'users',
      queryFn: fetchUsers,
    },
    {
      queryKey: 'products',
      queryFn: fetchProducts,
    },
    {
      queryKey: 'orders',
      queryFn: fetchOrders,
    },
  ];

  const results = useQueries(queryConfig);

  return (
    <div>
      <h1>Data List</h1>
      {results.map((result, index) => {
        const { isLoading, isError, data } = result;

        if (isLoading) {
          return <div key={index}>Loading...</div>;
        }

        if (isError) {
          return <div key={index}>Error occurred while fetching data.</div>;
        }

        return (
          <div key={index}>
            <h2>{queryConfig[index].queryKey}</h2>
            <ul>
              {data.map(item => (
                <li key={item.id}>{item.name}</li>
              ))}
            </ul>
          </div>
        );
      })}
    </div>
  );
};

const fetchUsers = async () => {
  const response = await fetch('https://api.example.com/users');
  const data = await response.json();
  return data;
};

const fetchProducts = async () => {
  const response = await fetch('https://api.example.com/products');
  const data = await response.json();
  return data;
};

const fetchOrders = async () => {
  const response = await fetch('https://api.example.com/orders');
  const data = await response.json();
  return data;
};

QueryCatch

리액트 쿼리의 QueryCache는 데이터를 캐싱하고 관리하는 데 사용되는 중앙 캐시 저장소다.

import { QueryCache, useQueryCache, useQuery } from 'react-query';

const queryCache = new QueryCache();

const UsersList = () => {
  const cache = useQueryCache();

  const { data, isLoading, isError } = useQuery('users', fetchUsers, {
    initialData: cache.getQueryData('users'), // 이전에 캐시된 데이터 사용
    initialStale: true, // 쿼리를 처음부터 다시 요청
    cacheTime: 60000, // 1분 동안 캐시 유지
  });

  // 데이터 가져온 후에 캐시 업데이트
  if (!isLoading && !isError) {
    cache.setQueryData('users', data);
  }

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

  if (isError) {
    return <div>Error occurred while fetching users.</div>;
  }

  return (
    <div>
      <h1>User List</h1>
      <ul>
        {data.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

const fetchUsers = async () => {
  const response = await fetch('https://api.example.com/users');
  const data = await response.json();
  return data;
};

useMutation

값을 바꿀때 사용하는 api 이다.
데이터를 post, update 하기위한 api 이다.

리액트 쿼리의 useMutation은 데이터의 생성, 수정 또는 삭제와 같은 변경 작업을 처리하는 데 사용되는 훅이다. 이 훅은 비동기 작업을 처리하고 상태를 관리하여 쉽게 데이터를 변경할 수 있도록 도와준다.

import { useMutation } from 'react-query';

function TodoForm() {
  const createTodo = async (data) => {
    // 서버로 데이터를 전송하는 비동기 함수
    const response = await fetch('/api/todos', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: {
        'Content-Type': 'application/json',
      },
    });

    if (!response.ok) {
      throw new Error('Todo 생성에 실패했습니다.');
    }

    return response.json();
  };

  const { mutate, isLoading, isError, error } = useMutation(createTodo);

  const handleSubmit = (e) => {
    e.preventDefault();

    const formData = new FormData(e.target);
    const todoData = Object.fromEntries(formData.entries());

    mutate(todoData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="title" placeholder="할 일" />
      <button type="submit" disabled={isLoading}>
        {isLoading ? '로딩 중...' : '추가'}
      </button>

      {isError && <div>에러: {error.message}</div>}
    </form>
  );
}

export default TodoForm;

글을 마치며

리액트 쿼리의 사용이유와 사용 예제들을 통해 리액트 쿼리와 한층 더 가까워 진 것 같아서 기분이 좋다. ^^ useQuery는 이해가 잘 됐지만 useMutation은 잘 와닿지 않았다...
리액트 쿼리에 대해 공부하면서 "앞으로 리액트 쿼리 공부를 열심히 해야겠다!" 라는 생각이 많이 들었다.

profile
프론트엔드 공부중

1개의 댓글

comment-user-thumbnail
2023년 6월 2일

useMutation은 개념만 공부해보고 실습에서 사용해보면서 차차 알아가봅시다.
좋은글이네요 수고했어요!!

답글 달기