Skip to content

Commit

Permalink
bonnie#2 Prefetching, useMutation
Browse files Browse the repository at this point in the history
  • Loading branch information
GyeongChan-Jang committed Sep 10, 2022
1 parent 5b034ee commit 6a3031f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 40 deletions.
50 changes: 31 additions & 19 deletions base-blog-em/src/PostDetail.jsx
Original file line number Diff line number Diff line change
@@ -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 <div>Loading...</div>
if (isError) return <div>{error.toString()}</div>

return (
<>
<h3 style={{ color: "blue" }}>{post.title}</h3>
<button>Delete</button> <button>Update title</button>
<h3 style={{ color: 'blue' }}>{post.title}</h3>
<button onClick={deleteMutation.mutate(post.id)}>Delete</button>
{deleteMutation.isError && <p style={{ color: 'red' }}>Error deleting the post</p>}
{deleteMutation.isLoading && <p style={{ color: 'purple' }}>deleting the post</p>}
{deleteMutation.isSuccess && <p style={{ color: 'green' }}>Post has (not) been deleted</p>}
<button onClick={updateMutation.mutate(post.id)}>Update title</button>
{updateMutation.isError && <p style={{ color: 'red' }}>Error updating the post</p>}
{updateMutation.isLoading && <p style={{ color: 'purple' }}>updating the post</p>}
{updateMutation.isSuccess && <p style={{ color: 'green' }}>Post has (not) been updated</p>}
<p>{post.body}</p>
<h4>Comments</h4>
{data.map((comment) => (
Expand All @@ -37,5 +49,5 @@ export function PostDetail({ post }) {
</li>
))}
</>
);
)
}
33 changes: 24 additions & 9 deletions base-blog-em/src/Posts.jsx
Original file line number Diff line number Diff line change
@@ -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 <div>Loading...</div>
if (isError) return <div>something went wrong</div>

Expand All @@ -27,11 +42,11 @@ export function Posts() {
))}
</ul>
<div className="pages">
<button disabled onClick={() => {}}>
<button disabled={currentPage <= 1} onClick={() => setCurrentPage((prev) => prev - 1)}>
Previous page
</button>
<span>Page {currentPage + 1}</span>
<button disabled onClick={() => {}}>
<span>Page {currentPage}</span>
<button disabled={currentPage >= maxPostPage} onClick={() => setCurrentPage((prev) => prev + 1)}>
Next page
</button>
</div>
Expand Down
19 changes: 7 additions & 12 deletions base-blog-em/src/index.js
Original file line number Diff line number Diff line change
@@ -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(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
ReactDOM.render(<App />, 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()

0 comments on commit 6a3031f

Please sign in to comment.