diff --git a/base-blog-em/src/PostDetail.jsx b/base-blog-em/src/PostDetail.jsx
index 2af258fc..b295cd02 100644
--- a/base-blog-em/src/PostDetail.jsx
+++ b/base-blog-em/src/PostDetail.jsx
@@ -1,34 +1,46 @@
+import { useQuery, useMutation } from 'react-query'
+
async function fetchComments(postId) {
- const response = await fetch(
- `https://jsonplaceholder.typicode.com/comments?postId=${postId}`
- );
- return response.json();
+ 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();
+ 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();
+ const response = await fetch(`https://jsonplaceholder.typicode.com/postId/${postId}`, {
+ method: 'PATCH',
+ data: { title: 'REACT QUERY FOREVER!!!!' }
+ })
+ return response.json()
}
export function PostDetail({ post }) {
- // replace with useQuery
- const data = [];
+ // 쿼리키를 배열로 만든다면 쿼리에 식별자를 추가하여 쿼리를 구분할 수 있음
+ // 비활성화된 쿼리는 캐시에서 제거되지 않음, 캐시 시간 이후에 가비지 컬렉터가 캐시에서 지움
+ // 비동기 함수를 화살표 함수로 만드는 것은 인수가 뭐든지간에 호출을 해야하기 때문에
+ const { data, isLoading, isError, error } = useQuery(['comments', post.id], () => fetchComments(post.id))
+
+ const deleteMutation = useMutation((postId) => deletePost(postId))
+ const updateMutation = useMutation((postId) => updatePost(postId))
+
+ if (isLoading) return
Loading...
+ if (isError) return {error.toString()}
return (
<>
- {post.title}
- Delete Update title
+ {post.title}
+ Delete
+ {deleteMutation.isError && Error deleting the post
}
+ {deleteMutation.isLoading && deleting the post
}
+ {deleteMutation.isSuccess && Post has (not) been deleted
}
+ Update title
+ {updateMutation.isError && Error updating the post
}
+ {updateMutation.isLoading && updating the post
}
+ {updateMutation.isSuccess && Post has (not) been updated
}
{post.body}
Comments
{data.map((comment) => (
@@ -37,5 +49,5 @@ export function PostDetail({ post }) {
))}
>
- );
+ )
}
diff --git a/base-blog-em/src/Posts.jsx b/base-blog-em/src/Posts.jsx
index 9404d664..3c33b3aa 100644
--- a/base-blog-em/src/Posts.jsx
+++ b/base-blog-em/src/Posts.jsx
@@ -1,19 +1,34 @@
-import { useState } from 'react'
-import { useQuery } from 'react-query'
+import { useEffect, useState } from 'react'
+import { useQuery, useQueryClient } 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')
+async function fetchPosts(pageNum) {
+ const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_limit=10&_page=${pageNum}`)
return response.json()
}
export function Posts() {
- const [currentPage, setCurrentPage] = useState(0)
+ const [currentPage, setCurrentPage] = useState(1)
const [selectedPost, setSelectedPost] = useState(null)
+ const queryClient = useQueryClient()
+
+ useEffect(() => {
+ if (currentPage < maxPostPage) {
+ const nextPage = currentPage + 1
+ queryClient.prefetchQuery(['posts', nextPage], () => fetchPosts(nextPage), {
+ staleTime: 2000,
+ // 이전 페이지로 돌아갔을 때 캐시에 해당 지난 데이터가 있도록
+ keepPreviousData: true
+ })
+ }
+ }, [currentPage, queryClient])
+
// replace with useQuery
- const { data, isError, isLoading } = useQuery('posts', fetchPosts, { staleTime: 2000 })
+ const { data, isError, isLoading } = useQuery(['posts', currentPage], () => fetchPosts(currentPage), {
+ staleTime: 2000
+ })
if (isLoading) return Loading...
if (isError) return something went wrong
@@ -27,11 +42,11 @@ export function Posts() {
))}
- {}}>
+ setCurrentPage((prev) => prev - 1)}>
Previous page
- Page {currentPage + 1}
- {}}>
+ Page {currentPage}
+ = maxPostPage} onClick={() => setCurrentPage((prev) => prev + 1)}>
Next page
diff --git a/base-blog-em/src/index.js b/base-blog-em/src/index.js
index ef2edf8e..09f66641 100644
--- a/base-blog-em/src/index.js
+++ b/base-blog-em/src/index.js
@@ -1,17 +1,12 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import './index.css';
-import App from './App';
-import reportWebVitals from './reportWebVitals';
+import React from 'react'
+import ReactDOM from 'react-dom'
+import './index.css'
+import App from './App'
+import reportWebVitals from './reportWebVitals'
-ReactDOM.render(
-
-
- ,
- document.getElementById('root')
-);
+ReactDOM.render( , document.getElementById('root'))
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
-reportWebVitals();
+reportWebVitals()