리액트 React/ReactQuery

2. React Query 설치 및 실행 / staleTime, cacheTime / 기본 코드

leexx 2023. 5. 18. 02:59

React Query 설치 및 실행

  1. React Query 설치
    • npm install react-query
  2. React Query Devtools 설치
    • npm install @tanstack/react-query-devtools
  3. query client 생성
    • cache 와 interact 하는 것
  4. queryProvider 적용
    • cache, client config 를 제공함
    • 3 에서 만든 query client 가 필요함
    • 모든 자식 컴포넌트들이 queryClient 를 사용할 수 있도록 함
  5. useQuery 실행
    • 서버에서 데이터 가져오기 위해 사용
    • hook 임

 

Stale, staleTime

  • Stale 해진다는것은?
    • 만료되었다는 의미
    • Data 는 stale 상태 에서만 데이터를 fetching 함
    • component remount, window refocus, ...
  • staleTime
    • 데이터의 max age
    • 데이터가 만료되었다고 판단하기 전까지의 시간, 즉 staleTime 이 2초면 데이터 fetching 이후 2초 동안은 데이터는 fresh 함

cacheTime

  • cacheTime 이 지나면 데이터를 expires 함, grabage collection 이 되고 client 는 데이터를 쓸 수 없음
  • default 는 5분

 

전체 코드

app.js

QueryClientProvider 세팅

ReactDevTools 세팅

 

더보기
import {QueryClient, QueryClientProvider} from "react-query";
import {ReactQueryDevtools} from "react-query/devtools";

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

const queryClient = new QueryClient();

function App() {
    return (
        // TODO provide React Query client to App
        <QueryClientProvider client={queryClient}>
            <div className="App">
                <h1>Blog Posts</h1>
                <Posts/>
            </div>
            <ReactQueryDevtools />
        </QueryClientProvider>
    );
}

export default App;

 

Blog Posts

useQuery 로 데이터 요청

더보기
import {useState} from "react";
import {useQuery} from 'react-query';

import {PostDetail} from "./PostDetail";

const maxPostPage = 10;

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

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

    // TODO replace with useQuery
    const {data, isError, error, isLoading, isFetching} = useQuery("posts", fetchPosts, {staleTime: 2000}); // queryKey, query를 가져오는 함수, option(staleTime - millisecond)
    if (isFetching) return <h3>Fetching...</h3> // 1.
    if (isLoading) return <h3>Loading...</h3>; // 2.
    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}/>}
        </>
    );
}