โ Posts.js
import React, { 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);
// replace with useQuery
const {data, isLoading, isError, error} = useQuery('posts', fetchPosts, {staleTime : 2000});
// ๋ง์ฝ ๋ก๋ฉ ์ค์ด๋ผ๋ฉด
if(isLoading){
return <h3>Loading...</h3>;
}
if(isError){
return (
<React.Fragment>
<h3>Sorry, no Data</h3>
<p>{error.toString()}</p>
</React.Fragment>
)
}
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} />}
</>
);
}
โ PostDetail.js
import { useQuery } from 'react-query';
async function fetchComments(postId) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/comments?postId=${postId}`
);
return response.json();
}
async function deletePost(postId) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/postId/${postId}`,
{ method: "DELETE" }
);
return response.json();
}
async function updatePost(postId) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/postId/${postId}`,
{ method: "PATCH", data: { title: "REACT QUERY FOREVER!!!!" } }
);
return response.json();
}
export function PostDetail({ post }) {
const {data, isLoading, isError} = useQuery('comments', ()=>fetchComments(post.id));
if(isLoading){
return <h3>Loading ...</h3>
}
if(isError){
return <h3>Sorry, error</h3>
}
return (
<>
<h3 style={{ color: "blue" }}>{post.title}</h3>
<button>Delete</button> <button>Update title</button>
<p>{post.body}</p>
<h4>Comments</h4>
{data.map((comment) => (
<li key={comment.id}>
{comment.email}: {comment.body}
</li>
))}
</>
);
}
- posts ์์ ํด๋น ๊ฒ์๊ธ์ ๊ธ์ ๋๋ฅด๋ฉด state ์ ๊ฐ์ผ๋ก post ์ data ๊ฐ ๋ค์ด๊ฐ๊ณ
- ํด๋น state ๋ props ๋ฅผ ํตํด์ PostDetail ์ปดํฌ๋ํธ๋ก ์ ๋ฌ์ด ๋ฉ๋๋ค.
- ๊ทธ๋ฆฌ๊ณ PostDetail ์ปดํฌ๋ํธ์์๋ useQuery ๋ฅผ ์ฌ์ฉํด fetchComments ์ฟผ๋ฆฌ ํจ์๊ฐ props ๋ก ์ ๋ฌ๋ฐ์ ์์ฑ ์ค id ๊ฐ์ ์ธ์๋ก ๋ฐ์ ๋น๋๊ธฐ ํจ์๋ฅผ ์คํ ํฉ๋๋ค.
- ๊ฒฐ๋ก ์ ์ผ๋ก ํด๋น post.id ์ ํด๋นํ๋ comment ๊ฐ ํ๋ฉด์ ๋ณด์ฌ์ ธ์ผ ํฉ๋๋ค.
- ํ์ง๋ง, ์๋๋ฅผ ๋ณด๋ฉด ๋ชจ๋ ๊ธ์ด ๊ฐ์ comment ๋ฅผ ํ๋ฉด์ ๋ณด์ฌ์ค๋๋ค.
๋ชจ๋ ๊ฐ์ comment ๊ฐ ๋ณด์ผ๊น โ
์์ ๋ณด์ด๋ comments ์ฟผ๋ฆฌ ํค๋ ์คํ 9์ 59๋ถ์ ๋ง์ง๋ง์ผ๋ก ์
๋ฐ์ดํธ๊ฐ ๋์์ต๋๋ค.
๋ค๋ฅธ ๊ฒ์๋ฌผ์ ๋๋ฌ๋ ๋ณํํ์ง ์์ผ๋ฉฐ, ๋ฐ์ดํฐ๋ ๋ง๋ฃ(stale) ๋์๊ณ , ๋ฆฌํจ์นญ ๋ํ ์ผ์ด๋์ง ์์ต๋๋ค.
๊ถ๊ทน์ ์ธ ์ด์ ๋, ๋ชจ๋ ์ฟผ๋ฆฌ๊ฐ comments ์ฟผ๋ฆฌ ํค๋ฅผ ๋์ผํ๊ฒ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ ์ ๋๋ค.
- ์ด๋ ๊ฒ comments ๊ฐ์ด ์๋ ค์ง ์ฟผ๋ฆฌ ํค๊ฐ ์์ ๋๋ ์ด๋ ํ ๋ณํ๊ฐ ์์ด์ผ๋ง ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ ธ์ค๊ฒ ๋ฉ๋๋ค.
- ๋ณํ์ ์์๋
- ์ปดํฌ๋ํธ๊ฐ ๋ค์ ๋ง์ดํธํ๊ฑฐ๋, ์๋์ฐ๋ฅผ ๋ค์ ํฌ์ปค์ค ํ ๋
- useQuery์์ ๋ฐํ๋์ด ์๋์ผ๋ก ๋ฆฌํจ์นญ์ ์คํํ ๋
- ์ง์ ๋ ๊ฐ๊ฒฉ์ผ๋ก ๋ฆฌํจ์นญ์ ์๋ ์คํํ ๋
- ๋ณ์ด(Mutation) ์ ์์ฑํ ๋ค ์ฟผ๋ฆฌ๋ฅผ ๋ฌดํจํ ํ ๋
ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๊ฐ ์๋ฒ์ ๋ฐ์ดํฐ์ ๋ถ์ผ์นํ ๋ ๋ฆฌํจ์นญ์ด ๋ฐ์ ํฉ๋๋ค.
ํ์ฌ ๊ฒ์๋ฌผ์ ์ ๋ชฉ์ ํด๋ฆญํ ๋๋ ์ด๋ฐ ๋ณํ๊ฐ ์ผ์ด๋์ง ์์ต๋๋ค.
- ๋ฐ๋ผ์ ๋ฐ์ดํฐ๊ฐ ๋ง๋ฃ๋์ด๋ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค์ง ์์ต๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ โ
- ์ ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ ์ ๋ชฉ์ ํด๋ฆญ ํ ๋๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ๋ฌดํจํ์์ผ์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ ธ์ค๊ฒ ๋ง๋ค ์ ์๋๋ฐ
- ๊ฐ๋จํ ๋ฐฉ๋ฒ๋ ์๋๊ณ , ์ํ๋ ๋ฐฉ๋ฒ๋ ์๋๋๋ค.
- ๋ฐ์ดํฐ๋ฅผ ์ ๊ฑฐํด์๋ ์๋ฉ๋๋ค.
- 2๋ฒ์งธ ๊ฒ์๋ฌผ์ ๋ํ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค ๋, ์บ์์์ ๊ฒ์๋ฌผ 1 ์ ๋ํ ๋๊ธ์ ์ ๊ฑฐํ์ง ์์์ผ ํฉ๋๋ค.
- ๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋๊ฒ ์๋๋ฉฐ ๊ฐ์ ์บ์ ๊ณต๊ฐ์ ์ฐจ์งํ์ง ์์ต๋๋ค.
- ์๋ฐํ ๋งํ๋ฉด 1๋ฒ์งธ ๊ฒ์๋ฌผ์ ๋๋ ์ ๋, ๊ฒ์๋ฌผ 1์ ๋ํ ์บ์ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
- 2๋ฒ์งธ ๊ฒ์๋ฌผ์ ๋ํ ๋ฐ์ดํฐ๋ก ๋ฎ์ด์ฐ๋ ๊ฑด ์ข์ง ์์ต๋๋ค.
- ์ฟผ๋ฆฌ๋ ๊ฒ์๋ฌผ id ๋ฅผ ํฌํจํ๊ธฐ ๋๋ฌธ์, ์ฟผ๋ฆฌ๋ณ๋ก ์บ์๋ฅผ ๋จ๊ธธ ์ ์์ผ๋ฉฐ comment ์ฟผ๋ฆฌ์ ๋ํ ์บ์๋ฅผ ๊ณต์ ํ์ง ์์๋ ๋ฉ๋๋ค.
- ๊ฐ ๊ฒ์๋ฌผ์ ๋ํ ์ฟผ๋ฆฌ์ ๋ผ๋ฒจ์ ์ค์ ํ๋ฉด ๋ฉ๋๋ค.
โ Array as Query Key
์ฟผ๋ฆฌ ํค์ ๋ฌธ์์ด(String) ๋์ ๋ฐฐ์ด(Array) ์ ์ ๋ฌํ๋ฉด ๊ฐ๋ฅ ํฉ๋๋ค.
['comment', post.id]
- ์์ ๊ฐ์ ๊ฒฝ์ฐ ๋ฐฐ์ด์ ์ฒซ ๋ฒ์งธ ์์๋ก ๋ฌธ์์ด "comment" ๋ฅผ ๊ฐ์ง๊ณ , ๋ ๋ฒ์งธ ์์๋ก post.id ๋ฅผ ๊ฐ์ง๋๋ค.
- ์ฟผ๋ฆฌ ํค๋ฅผ ์ฟผ๋ฆฌ์ ๋ํ ์์กด์ฑ ๋ฐฐ์ด๋ก ์ทจ๊ธํ๊ฒ ๋ฉ๋๋ค.
- ์ฟผ๋ฆฌ ํค๊ฐ ๋ณ๊ฒฝ๋๋ฉด, ์ฆ post.id ๊ฐ ์ ๋ฐ์ดํธ๋๋ฉด React Query๊ฐ ์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํด์ staleTime ๊ณผ cacheTime ์ ๊ฐ์ง๊ฒ ๋๊ณ ์์กด์ฑ ๋ฐฐ์ด์ด ๋ค๋ฅด๋ค๋ฉด ์์ ํ ๋ค๋ฅธ ๊ฒ์ผ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
- ๋ฐ๋ผ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉํ๋ ์ฟผ๋ฆฌ ํจ์์ ์๋ ๊ฐ์ด ์ฟผ๋ฆฌ ํค์ ํฌํจ๋์ด์ผ ํฉ๋๋ค.
- ๊ทธ๋ ๊ฒ ๋๋ฉด ๋ชจ๋ comment ์ฟผ๋ฆฌ๊ฐ ๊ฐ์ ์ฟผ๋ฆฌ๋ก ๊ฐ์ฃผ๋๋ ์ํฉ์ ๋ง๊ณ ๊ฐ ๋ค๋ฅธ ์ฟผ๋ฆฌ๋ก ๋ค๋ค์ง ๊ฒ ์ ๋๋ค.
์ ์ฉ
โ PostDetail.js
// ์ด์ ์์
const {data, isLoading, isError} = useQuery('comments', ()=>fetchComments(post.id));
// ์๋ ์ฒ๋ผ ๋ณ๊ฒฝ
const {data, isLoading, isError} = useQuery(['comments', post.id], ()=>fetchComments(post.id));
- fetchComments ์ ์ ๋ฌํ ๊ฒ๊ณผ ๋์ผํ post.id ์ ๋๋ค.
- post.id ๊ฐ ์์กด์ฑ ๋ฐฐ์ด๋ก ์์ฉํ๋ฉฐ ๋ฌธ์์ด 'comments' ์ ์๋ณ์๊ฐ ์ถ๊ฐ๋ ์ ์ ๋๋ค.
- ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ๋ณด๋ฉด ํด๋นํ๋ ๋๊ธ์ id ๊ฐ ๋ค ๋ค๋ฅธ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
- ์ด๋ ๋ค๋ฅธ ๊ฒ์๋ฌผ์ ํด๋ฆญํ์๋ง์ ๊ทธ ์ ์ ์ฟผ๋ฆฌ๊ฐ ๋นํ์ฑํ ๋๋ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ ์์ง ์บ์์ ์๋ ์ํ ์ ๋๋ค.
- ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ก ์์ง๋๊ธฐ ์ ๊น์ง ์บ์์ ๋จ์์์ ๊ฒ ์ ๋๋ค.
- ๋ํ ๊ฒ์๋ฌผ์ ๋๊ธ์ด ๋ณํ๋ ๊ฑธ ๋ณผ ์ ์์ต๋๋ค.
โ ์ฐธ๊ณ
'๐ Front-End > React.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
React Query - ๋ฐ์ดํฐ ํ๋ฆฌํจ์นญ(Pre-fetching) (0) | 2022.10.25 |
---|---|
React Query - ํ์ด์ง ๋งค๊น(Pagination) (0) | 2022.10.25 |
React Query - staleTime vs cacheTime (0) | 2022.10.25 |
React Query - Dev Tools (0) | 2022.10.25 |
React Query - ๋ก๋ฉ ๋ฐ ์ค๋ฅ ์ํ (0) | 2022.10.25 |