Cliente State vs. Server State
- Client state: user’s chosen language or theme.
- Server state: information stored on server
React Query, 3가지 키워드
- Query - 어떤 데이터에 대한 요청을 의미한다.
- Mutation - 어떤 데이터를 바꾸는(추가, 수정, 삭젝) 것이다.
- Query Invalidation - 쿼리를 무효화 시킨다.
React Query 실행 순서
1. React Query 설정
npm install react-query
2. Create query client: 쿼리와 서버의 데이터 캐시를 관리하는 클라이언트
3. Apply QueryProvider: 자녀 컴포넌트에 캐시와 클라이언트 구성을 제공한다.
4. useQuery: 서버에서 데이터를 가져온다면, run useQuery
isFetching vs. isLoading
isFetching - async query function hasn’t yet resolved
- 비동기 쿼리가 해결되지 않았음을 의미한다.
- 이경우에는 아직 fetching을 완료하지 않았다는 의미지만 쿼리가 Axios 호출 또는 GraphQL 호출일 수도 있다. 이것이 isFetching이다.
isLoading - no cached data, plus isFetching
- 가져오는 상태에 있음을 의미한다.
- 쿼리 함수가 아직 해결되지 않은 것이다.
- 그리고 캐시 된 데이터도 없다. 이 쿼리를 만든 적이 없다는 의미이다. 데이터를 가져오는 중이고 표시할 캐시 데이터도 없다는 것이다.
렌덤 블로그 글 API로 쿼리 생성 및 로딩
App.jsx
import { Posts } from './Posts';
import './App.css';
import { QueryClient, QueryClientProvider } from 'react-query';
// 클라이언트 생성 - 이제 클라이언트가 있기 때문에 공급자를 추가할 수 있다. 공급자가 클라이언트를 통해 클라이언트가 가지고 있는 캐시와 모든 기본 옵션을 공급자의 자녀 컴포넌트도 사용 할 수 있게 된다.
const queryCleint = new QueryClient();
function App() {
return (
// provide React Query client to App
// 이제 여기 안에는 리액트 쿼리를 사용할 수 있다.
// Posts안에 써보기.
<QueryClientProvider client={queryCleint}>
<div className='App'>
<h1>Blog Posts</h1>
<Posts />
</div>
</QueryClientProvider>
);
}
export default App;
Posts.jsx
import { useState } from 'react';
// 1. import useQuery
// 서버에서 데이터를 가져올 때 사용된다.
import { useQuery } from 'react-query';
import { PostDetail } from './PostDetail';
const maxPostPage = 10;
// 비동기, fetchPosts가 해결될 때까지 아래의 {data}는 useQuery에서 정의되지 않는다.
// useQuery는 fetchPosts가 데이터와 반환되지 않은 경우 데이터에 할당할 항목을 알 수 없기 때문이다.
async function fetchPosts() {
const response = await fetch('https://jsonplacㄴㅇㄹㅈㄷㄹㄴㅇㄹeholderssdfsf.typicode.com/posts?_limit=10&_page=0');
return response.json();
}
export function Posts() {
const [currentPage, setCurrentPage] = useState(0);
const [selectedPost, setSelectedPost] = useState(null);
// replace with useQuery
// 데이터는 더이상 hard coded array가 아닌
// const data = [];
// 반환 객체에서 useQuery로 데이터 속성을 구조분해한다.
// useQuery는 다양한 속성을 가진 객체를 반환한다.
// useQuery(쿼리 키(이름), 쿼리에 대한 데이터를 가져오는 방법)
const { data, isLoading } = useQuery('posts', fetchPosts);
// fetchPosts가 완료되면 data에 배열이 포함된다.
if (isLoading) return <h3>Loading...</h3>;
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} />}
</>
);
}
아래와 같이 데이터의 fetch가 안 끝난 상태에서 Loading... 이 뜨고 fetching이 완료되면 게시물들이 보인다.
isError과 error을 추가해 준 뒤 fetch 하는 주소를 조금 바꿔서 에러를 내보았다.
(useQuery는 fetch를 총 3번 시도한 후 loading이 되지 않으면 error을 내보낸다.)
import { useState } from 'react';
// 1. import useQuery
// 서버에서 데이터를 가져올 때 사용된다.
import { useQuery } from 'react-query';
import { PostDetail } from './PostDetail';
const maxPostPage = 10;
// 비동기, fetchPosts가 해결될 때까지 아래의 {data}는 useQuery에서 정의되지 않는다.
// useQuery는 fetchPosts가 데이터와 반환되지 않은 경우 데이터에 할당할 항목을 알 수 없기 때문이다.
async function fetchPosts() {
const response = await fetch('https://jsonplac에러가뜰꺼야eholderssdfsf.typicode.com/posts?_limit=10&_page=0');
return response.json();
}
export function Posts() {
const [currentPage, setCurrentPage] = useState(0);
const [selectedPost, setSelectedPost] = useState(null);
// replace with useQuery
// 데이터는 더이상 hard coded array가 아닌
// const data = [];
// 반환 객체에서 useQuery로 데이터 속성을 구조분해한다.
// useQuery는 다양한 속성을 가진 객체를 반환한다.
// useQuery(쿼리 키(이름), 쿼리에 대한 데이터를 가져오는 방법)
const { data, isError, error, isLoading } = useQuery('posts', fetchPosts);
// fetchPosts가 완료되면 data에 배열이 포함된다.
if (isLoading) return <h3>Loading...</h3>;
if (isError)
return (
<>
<h3>Oops, something went wrong</h3>
<p>{error.toString()}</p>
</>
);
return (
<>
...
</>
);
}
'개발 일지 > TIL' 카테고리의 다른 글
[ TypeScript ] TypeScript 설치 및 파일 생성 (0) | 2023.01.21 |
---|---|
[ React Query ] 게시물에 따른 comments 업데이트 (0) | 2023.01.21 |
[ WebSocket ] 채팅기능 구현(1) - port에 서버 뛰우기 (0) | 2023.01.18 |
[ TypeScript ] 제네릭 & 타입 추론 (0) | 2023.01.17 |
[ TypeScript ] Interface & Intersection Type (0) | 2023.01.17 |
댓글