์ฝ๋ ๊ตฌ์กฐ
โ App.js
import { Posts } from "./Posts";
import "./App.css";
function App() {
return (
// provide React Query client to App
<div className="App">
<h1>Blog Posts</h1>
<Posts />
</div>
);
}
export default App;
โ Posts.js
import { useState } from "react";
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 = [];
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} />}
</>
);
}
โ ์ค์ ์ผ๋ก ๋ด์ผํ ๋ถ๋ถ
- useQuery ๋ฅผ ์ฌ์ฉํ ๋, ์์ ์๋ fetchPosts ํจ์๋ฅผ ์ฌ์ฉํด์ JSONPlaceholder ์๋ฒ์์ ๊ฒ์๋ฌผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๊ฒ ์ ๋๋ค.
- Posts ๋ฐ์ดํฐ์ ๋ํ useQuery ์์ ๊ฐ์ฅ ๊ด์ฌ ์๊ฒ ๋ด์ผํ ๋ถ๋ถ์ ์๋ ๊ฒ์๋ฌผ ๋ฐ์ดํฐ๋ฅผ ๋งคํํ๋ ๋ถ๋ถ ์ ๋๋ค.
const data = [];
<ul> {data.map((post) => (
<li key={post.id} className="post-title" onClick={() => setSelectedPost(post)} >
{post.title}
</li> ))}
</ul>
- ์ง๊ธ ๋ฐ์ดํฐ๋ ๋น ๋ฐฐ์ด(Array)๋ก ๋์ด ์์ง๋ง, ์ด๊ฒ์ useQuery ๋ก ๋์ฒดํ ๊ฒ ์ ๋๋ค.
- Posts ์ปดํฌ๋ํธ์๋ state ์ button ๋ฑ๋ ์์ง๋ง ์ด๋ฐ ๋ถ๋ถ์ ๊ฐ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
- ๊ฐ์ฅ ๋จผ์ App.js ์์ React Query ์ฉ ์ฟผ๋ฆฌ ํด๋ผ์ด์ธํธ๋ฅผ ๋ง๋ค๊ณ ๋ชจ๋ ์๋ ์ปดํฌ๋ํธ๊ฐ ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํ๋, QueryProvider ๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค.
โ QueryProvider
import { QueryClient, QueryClientProvider } from 'react-query';
const queryClient = new QueryClient(); // ํด๋ผ์ด์ธํธ๊ฐ ์๊ธฐ ๋๋ฌธ์ provider ๋ฅผ ์ถ๊ฐ ํ ์ ์์ต๋๋ค.
- ์์ ๊ฐ์ด ์ค์ ์ ํ๋ฉด provider(๊ณต๊ธ์) ๊ฐ ํด๋ผ์ด์ธํธ๋ฅผ ์ํ์ผ๋ก ์ฌ์ฉํ๊ฒ ๋๋ฉด์
- ํด๋ผ์ด์ธํธ๊ฐ ๊ฐ์ง๊ณ ์๋ ์บ์์ ๋ชจ๋ ๊ธฐ๋ณธ ์ต์ ์ ๊ณต๊ธ์์ ์๋ ์ปดํฌ๋ํธ๋ ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
import { Posts } from "./Posts";
import "./App.css";
import { QueryClient, QueryClientProvider } from 'react-query';
const queryClient = new QueryClient(); // ํด๋ผ์ด์ธํธ๊ฐ ์๊ธฐ ๋๋ฌธ์ provider ๋ฅผ ์ถ๊ฐ ํ ์ ์์ต๋๋ค.
function App() {
return (
// provide React Query client to App
<QueryClientProvider client={queryClient}>
<div className="App">
<h1>Blog Posts</h1>
<Posts />
</div>
</QueryClientProvider>
);
}
export default App;
- ์ด์ QueryClientProvider ์์ ์๋ ๋ชจ๋ ์ปดํฌ๋ํธ๋ค์ React Query ํ ์ ์ฌ์ฉ ํ ์ ์์ต๋๋ค.
โ ๊ณต๊ธ์ ์ ์ปดํฌ๋ํธ์์ useQuery ๊ฐ์ ธ์ค๊ธฐ
import { useQuery } from 'react-query';
- useQuery ๋ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉํ ํ ์ ๋๋ค.
โuseQuery ์ฌ์ฉ๋ฒ
- ์ด์ ์๋ ์ฝ๋๋ฅผ useQuery ๋ก ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค.
const data = [];
โ useQuery ์ ์ฉ
const {data} = useQuery('query key', 'query function');
- useQuery ๋ ๋ค์ํ ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ฐํ ํฉ๋๋ค.
- ๊ทธ ์ค, ์ง๊ธ์ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐ ๋ถํด ํ๊ฒ ์ต๋๋ค.
- ๊ตฌ์กฐ ๋ถํด ํ ๋น ๊ตฌ๋ฌธ์ ๋ฐฐ์ด์ด๋ ๊ฐ์ฒด์ ์์ฑ์ ํด์ฒดํ์ฌ ๊ทธ ๊ฐ์ ๊ฐ๋ณ ๋ณ์์ ๋ด์ ์ ์๊ฒ ํ๋ JavaScript ํํ์์ ๋๋ค.
- useQuery ๋ ๋ช ๊ฐ์ง ์ธ์๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ฒซ ๋ฒ์งธ๋ ์ฟผ๋ฆฌ ํค ์ ๋๋ค. ๋ฐ๋ก ์ฟผ๋ฆฌ ์ด๋ฆ์ ๋งํ๋ ๊ฒ ์ ๋๋ค.
- ๊ทธ ๋ค์์ ์ฟผ๋ฆฌ ํจ์ ๋ฅผ ์ฌ์ฉ ํฉ๋๋ค. ์ฟผ๋ฆฌ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ ๋งํ๋ ๊ฒ ์ ๋๋ค.
const {data} = useQuery('posts', fetchPosts);
- ๋ ๋ฒ์งธ ์ฟผ๋ฆฌ ํจ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋น๋๊ธฐ ํจ์ ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. (axios ๋ฑ..)
- fetchPosts ๋ ํฌ์คํ ์ฒ์์ ์๋ ๋น๋๊ธฐ ํจ์ ์ฝ๋ ์ ๋๋ค.
- ์์ ๋ค์ด์๋ ๋ฐ์ดํฐ์ ๋ชจ์์ ์๋์ ๊ฐ์ต๋๋ค.
<ul>
{data.map((post) => (
<li
key={post.id}
className="post-title"
onClick={() => setSelectedPost(post)}
>
{post.title}
</li>
))}
</ul>
- ์ด์ ๋งตํํ data ๋ useQuery ๋ฅผ ํตํด(์ฟผ๋ฆฌํจ์) ๊ฐ์ ธ์จ fetchPosts ์์ ๋ฐํ๋ ๋ฐ์ดํฐ๊ฐ ๋ฉ๋๋ค.
- ์์ ์ฌ์ง์ ์๋ ๋ฐฐ์ด์ ๊ฐ ํญ๋ชฉ์ ๋ํ ๋ชฉ๋ก์ ๋ง๋ค๊ณ , ๊ฒ์๋ฌผ์ ์ ๋ชฉ์ ํ์ํ ๊ฒ ์ ๋๋ค.
- ํ์ง๋ง npm start ๋ฅผ ํตํด ์คํํ๋ฉด ์๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ ํฉ๋๋ค.
- ์ด์ ๋, ๋งคํ์ ์๋ํ์ง๋ง ๋งต์ ๋ฐฐ์ด ์ ์ฉ ์ด๊ธฐ ๋๋ฌธ์, ํ์ฌ ๋ฐ์ดํฐ๊ฐ ์ ์๋์ง ์์๋ค๊ณ ๋์ค๋ ๊ฒ ์ ๋๋ค.
- ๋ฐ๋ก, fetchPosts ๊ฐ ๋น๋๊ธฐ์์ด๊ธฐ ๋๋ฌธ์ fetchPosts ๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ์ด ๋ฐ์ดํฐ๋ useQuery ์์ ์ ์๋์ง ์์ ๊ฒ ์ ๋๋ค.
- useQuery ๋ fetchPosts ๊ฐ ๋ฐ์ดํฐ์ ๋ฐํ๋์ง ์์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ์ ํ ๋นํ ํญ๋ชฉ์ ์ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ๋์ค์ ์ข ๋ ์ข์ ๋ฐฉ๋ฒ์ผ๋ก ํด๊ฒฐํ ์์ ์ด์ง๋ง, ์ฐ์ ์กฐ๊ฑด๋ฌธ์ ํตํด ํด๊ฒฐํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
โ ๋น๋๊ธฐ ๋ฌธ์ ํด๊ฒฐ
// replace with useQuery
const {data} = useQuery('posts', fetchPosts);
// ๋ฐ์ดํฐ๊ฐ ์ ์๋์ง ์์ ๊ฒฝ์ฐ
// fetchPosts ๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ๋ฐ์ดํฐ๋ ๊ฑฐ์ง์ด ๋ฉ๋๋ค.
if(!data){
return <div></div>;
}
// ํ์ง๋ง, fetchPosts ๊ฐ ํด๊ฒฐ๋๋ฉด, ๋ฐ์ดํฐ์ ๋ฐฐ์ด์ด ํฌํจ๋๊ณ
// ์ปดํฌ๋ํธ๊ฐ ๋ค์ ๋ ๋๋ง ๋์ด ๋งคํ ํ ์ ์๊ฒ ๋ฉ๋๋ค. ์๋ return ๋ฌธ
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} />}
</>
);
- ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ์ด ๋ณด์ด๊ฒ ๋ฉ๋๋ค.
- ๋ฒํผ์ ๋๋ฅด๋ฉด ๊ฒ์๋ฌผ๋ ๋ณผ ์ ์์ต๋๋ค.
- ๋ค์ ํฌ์คํ ์ uesQuery ์ ๋ก๋ฉ ๋ฐ ์ค๋ฅ ์ํ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
โ ์ฐธ๊ณ
'๐ Front-End > React.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
React Query - Dev Tools (0) | 2022.10.25 |
---|---|
React Query - ๋ก๋ฉ ๋ฐ ์ค๋ฅ ์ํ (0) | 2022.10.25 |
React Query โ (0) | 2022.10.25 |
Redux Toolkit (0) | 2022.10.25 |
React - SVG ํ์ผ ์ฌ์ฉ๋ฒ (0) | 2022.10.25 |