[#기본] React-Query로 데이터 fetching 하기
유데미, React Query: Server State Management in React 강의를 바탕으로 작성한 글입니다.
React Query를 공부하면서 챕터별로 배운내용을 정리하려고 합니다.
React Query를 목적/기능별로 어떻게 사용해야하는지 코드로 구분해 설명합니다.
css는 styled-components를 사용했습니다.
작업한 코드는 "여기" 브랜치, features/react-query에서 확인 가능합니다.
아래화면은 코드를 모두 작성하면 확인 가능한 화면입니다.
화면설명
'아래문장을 클릭해보세요' 문구 아래,
내용을 클릭하면, react-query가 클릭한 내용에 해당하는 아이템을 fetching 해오고 있습니다.
폴더구조
- Components : 컴포넌트 파일을 담는 폴더 입니다
- basic: react-query의 기본 기능(fetching)을 구현한 파일들을 담고 있습니다.
- pagination:react-query로 pagination을 구현한 파일들을 담고 있습니다.[다음장에서 다루겠습니다.]
- Server: Fetcher 파일에는 api 주소를 모두 저장하고 있는 파일입니다.
- Views/Asssets/Style: global 스타일을 설정하는 곳입니다.
Item.jsx
import React, { useState } from "react";
import { useQuery } from "react-query";
import { fetchPost } from "../../Server/Fetcher.js";
import ItemDetail from "./ItemDetail";
function Item() {
const [selectedPost, setSelectedPost] = useState(null);
const { isLoading, isError, error, data } = useQuery("posts", fetchPost);
if (!data) return <div />;
if (isLoading) return <h1>로딩중입니다..</h1>;
return (
<>
{!isError ? (
<div className="content">
<strong>아래 문장을 클릭해보세요</strong>
<ul className="click-item">
{data.map((post) => (
<li key={post.id} onClick={() => setSelectedPost(post)}>
{post.title}
</li>
))}
</ul>
{selectedPost && <ItemDetail post={selectedPost} />}
</div>
) : (
<div>
<h2>에러가 발생했습니다!</h2>
<p>{error}</p>
</div>
)}
</>
);
}
export default Item;
코드설명
const { isLoading, isError, error, data } = useQuery("posts", fetchPost,;
isLoading, isError, error, data는 useQuery에 내장되어 있는 기본 프로퍼티이다.
구조분해{}를 통해 값을 가져온다
- isLoading: true/fase 값을 가지며, Loading일때, 아닐때 경우를 갖고 싶을 때 사용할 수 있다.
- isError : true/fase 값을 가지며 isLoading과 내용은 같다.
- error : 구체적으로 어떤 에러인지를 알려준다.
- (중요) data : api에서 가져온 데이터가 담긴다
- (중요) posts : ""안에 들어간 값은 useQuery가 api를 가져올 때 , 어떤 키로 가져올 것인가를 의미한다. ""안에 들어간 텍스트는 유니크해야한다. posts라고 하지 않아도 된다. 자유롭게 작성해도 된다.여러 post를 가지고 온다고 posts라고 한 것이다.
- (중요) fetchPost : api를 fetching 하는 함수다, 위 코드에서 fetcher.js에 들어있다. 함수명을 적어준다.
if (!data) return <div />;
...중략...
<ul className="click-item">
{data.map((post) => (
<li key={post.id} onClick={() => setSelectedPost(post)}>
{post.title}
</li>
))}
</ul>
data가 undefined 될 경우, 위와 같이 처리한다.
ItemDetail.jsx
import React from "react";
function ItemDetail({ post }) {
return (
<>
<h4 className="title">Title: {post.title}</h4>
<p>{post.body}</p>
</>
);
}
export default ItemDetail;
Fetcher.js
const BaseUrl = `https://jsonplaceholder.typicode.com/posts?_limit=10&_page=0`;
export const fetchPost = async () => {
const response = await (await fetch(BaseUrl)).json();
return response;
};
GlobalStyle.js
import {createGlobalStyle} from 'styled-components';
const GlobalStyle = createGlobalStyle`
html, body, *{
margin:0; padding:0; box-sizing:border-box;
}
a{ text-decoration:none;}
ul, li{ list-style:none;}
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
legend { border: 0; padding: 0; }
textarea { overflow: auto; }
optgroup { font-weight: bold; }
table { border-collapse: collapse; border-spacing: 0; }
td, th { padding: 0; }
main,nav,footer{display:block; width:100%;}
`
export default GlobalStyle
페이지 전체의 스타일을 정의합니다.
App.js
import Items from "./Components/basic/Items";
import { ReactQueryDevtools } from "react-query/devtools";
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<div className="App">
<h1 className="title">Blog Posts</h1>
<Items />
</div>
<ReactQueryDevtools />
</QueryClientProvider>
);
}
export default App;
import { ReactQueryDevtools } from "react-query/devtools";
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
...중략...
<QueryClientProvider client={queryClient}>
...중략...
<ReactQueryDevtools />
</QueryClientProvider>
useQuery를 쓰기위한 기본 세팅이다.
ReactQueryDevtools는 데브툴즈다
index.css
- 스타일은 react-query와 별개의 것이라 참고만 하면 된다.
body {
margin: 0;
font-family: sans-serif;
background: #222;
color: #ddd;
text-align: center;
}
.App {
width: 960px;
margin: 0 auto;
}
.content {
text-align: left;
}
li {
cursor: pointer;
display: flex;
}
h1,
h2,
h3,
h4 {
color: #ffff57;
font-size: 4em;
letter-spacing: 2px;
}
.title {
text-align: left;
margin-bottom: 10px;
border-bottom: 1px solid;
}
button {
margin: 0 10px;
background: transparent;
border: 3px solid #ccc;
border-radius: 20px;
padding: 10px;
color: #ccc;
font-size: 1.2em;
cursor: pointer;
}
button:hover {
color: #fff;
border-color: #fff;
}
.post-title {
color: pink;
font-size: 30px;
margin: 10px 0;
}
.pages-buttons {
display: flex;
justify-content: space-between;
margin: 20px 0 20px 0;
}
.middle {
display: inline-block;
vertical-align: top;
margin-top: 20px;
}
.click-item {
margin-bottom: 20px;
}
.li-title,
.li-content {
display: inline-block;
vertical-align: top;
}
.li-title {
margin-right: 10px;
}
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "./index.css";
import GlobalStyle from "./Views/Assets/Style/GlobalStyle";
ReactDOM.render(
<React.StrictMode>
<GlobalStyle />
<App />
</React.StrictMode>,
document.getElementById("root")
);
Author And Source
이 문제에 관하여([#기본] React-Query로 데이터 fetching 하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rohkorea86/기본-React-Query로-데이터-fetching-하기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)