Read Detail
DetailPage 라우트 추가
- pages 디렉토리에
DetailPage.jsx
생성하고 라우트 추가하기
- post의
id
를 URL 파라미터로 지정
src/routes.js
import HomePage from './pages/HomePage';
import CreatePage from './pages/CreatePage';
import EditPage from './pages/EditPage';
import ListPage from './pages/ListPage';
import DetailPage from './pages/DetailPage';
const routes = [
{
path:'/',
element: <HomePage />
},
{
path:'/blogs',
element: <ListPage />
},
{
path:'/blogs/create',
element: <CreatePage />
},
{
path:'/blogs/edit',
element: <EditPage />
},
{
path:'/blogs/:id',
element: <DetailPage />
},
]
export default routes;
Detail 페이지 작성
- react router의
useParams
Hook을 사용하여 URL로부터 post의 id
를 받아오고 axios get 요청을 하여 post 정보 받아오기 (getPost
)
- 이전에 만든 LoadingSpinner 컴포넌트를 사용하여 로딩중일 경우에는 LoadingSpinner 출력하도록 작성
getPost
를 한번만 실행하도록 useEffect
사용하고 id가 변경될 때마다 함수 실행하도록 의존성 배열을 [id]
로 설정
src/pages/DetailPage.jsx
import React, { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import axios from 'axios'
import LoadingSpinner from '../components/LoadingSpinner'
function DetailPage() {
const { id } = useParams();
const [post, setPost] = useState(null);
const [loading, setLoading] = useState(true);
const getPost = (id) => {
axios.get(`http://localhost:3001/posts/${id}`)
.then((res) => {
setPost(res.data)
setLoading(false)
})
}
useEffect(() => {
getPost(id)
}, [id])
if (loading) {
return <LoadingSpinner />
}
return (
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
)
}
export default DetailPage
/blogs/:id
로 접근시 DetailPage
로 이동 확인
Detail Page 링크 추가
- 카드를 클릭하면 해당 Post의 DetailPage로 이동하도록 코드 수정
src/pages/ListPage.jsx
...
import { useNavigate } from 'react-router-dom'
function ListPage() {
...
const navigate = useNavigate();
if (posts.length === 0) {
return (<div>'No blog posts found'</div>)
}
return posts.map(post => {
return (
<Card
key={post.id}
title={post.title}
onClick={() => navigate(`/blogs/${post.id}`)}>
<button
className="btn btn-danger btn-sm"
onClick={(event) => deleteBlog(event, post.id)}>
Delete</button>
</Card>
)
})
}
...
export default ListPage
Post 생성 시간 추가하기
- Post를 Create 할 때 생성시간도 함께 저장하도록
BlogForm
수정
src/components/BlogForm.jsx
...
function BlogForm() {
...
const onSubmit = () => {
axios.post('http://localhost:3001/posts', {
title: title,
body: body,
createdAt: Date.now()
}).then(() => {
navigate('/blogs')
})
}
...
export default BlogForm
- 새로운 게시글 작성 후 생성 시간 함께 저장되는 것 확인
- 생성시간이 저장되어 있지 않은 데이터들은 삭제하고 계속 진행
- 게시글 DetailPage에 생성 시간 출력하도록 수정
src/pages/DetailPage.jsx
...
function DetailPage() {
...
if (loading) {
return <LoadingSpinner />
}
return (
<div>
<h1>{post.title}</h1>
<small class="text-muted">{post.createdAt}</small>
<p>{post.body}</p>
</div>
)
}
export default DetailPage
- 생성시간 함께 출력되지만 우리가 알아볼 수 없는 형태임
- 우리가 알아볼 수 있는 형태로 출력하도록 코드 수정
...
function DetailPage() {
...
const printDate = (timestamp) => {
return new Date(timestamp).toLocaleString();
}
if (loading) {
return <LoadingSpinner />
}
return (
<div>
<h1>{post.title}</h1>
<small class="text-muted">작성 시간 : {printDate(post.createdAt)}</small>
<p>{post.body}</p>
</div>
)
}
export default DetailPage
- 출력 확인
이런 유용한 정보를 나눠주셔서 감사합니다.