본문 바로가기
State Management Tools/React-Query

[React-Query v3] 리액트 쿼리 간단히 적용해보기

by NFAP0221S 2022. 7. 9.

쿼리 생성하기

1. 리액트 쿼리 라이브러리를 다운로드한다.

npm i react-query

 

2. 쿼리를 사용할 모든 컴포넌트의 최상위 부모 컴포넌트에서 쿼리 클라이언트를 공급한다. (여기서는 app.js 에서 공급)

import { Posts } from "./Posts";
import "./App.css";

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

// 1. 쿼리 클라이언트 생성
// Client를 생성하면 Provider를 모든 자식 컴포넌트에 클라이언트를 사용할 수 있게 한다.
const queryClient = new QueryClient();

function App() {
  return (
    // 2. Provider를 사용하여 모든 자식 컴포넌트에 클라이언트 추가, 이후 Posts로 이동
    <QueryClientProvider client={queryClient}>
      <div className="App">
        <h1>Blog Posts</h1>
        <Posts />
      </div>
    </QueryClientProvider>
  );
}

export default App;

이제 app의 모든 자식 컴포넌트는 쿼리를 사용할 수 있다.

 

useQuery 사용하기

import { useState } from "react";
import { useQuery } from "react-query";

import { PostDetail } from "./PostDetail";
const maxPostPage = 10;

async function fetchPosts() {
  const response = await fetch(
    "Ahttps://jsonplaceholder.typicode.com/posts?_limit=10&_page=0"
  );
  return response.json();
}

export function Posts() {
  const [currentPage, setCurrentPage] = useState(0);
  const [selectedPost, setSelectedPost] = useState(null);

  // 3. data에 useQuery를 구조분해할당 , (쿼리 키, 비동기 함수)
  // isLoading: 데이터가 로딩 중인지의 여부를 알려줌
  // isError:   데이터를 가져올 때, 오류가 있는지의 여부를 알려줌
  // error:     오류를 표시할 수 있다.
  const { data, isError, error, isLoading } = useQuery("posts", fetchPosts);
  if (isLoading) return <h3>Loading...</h3>;
  if (isError)
    return (
      <>
        <h3>Oops, something went wrong</h3>
        <p>{error.toString()}</p>
      </>
    );

  return (
    <>
      <ul>
        {data.map((post) => (
          <li
            key={post.id}
            className="post-title"
            onClick={() => setSelectedPost(post)}
          >
            {post.title}
          </li>
        ))}
      </ul>
      <div className="pages">
        <button disabled onClick={() => {}}>
          Previous page
        </button>
        <span>Page {currentPage + 1}</span>
        <button disabled onClick={() => {}}>
          Next page
        </button>
      </div>
      <hr />
      {selectedPost && <PostDetail post={selectedPost} />}
    </>
  );
}