35 블로그 페이지 라우트 추가
Card를 누르면 수정하는 페이지가 아닌 블로그 내용을 보여주는 페이지로 이동하고 싶음
새로운 라우트 추가
id에 맞는 블로그 내용을 화면에 출력
src 밑에 routes.js 파일 열기
routes.js
import HomePage from './pages/HomePage';
import CreatePage from './pages/CreatePage';
import EditPage from './pages/EditPage';
import ListPage from './pages/ListPage';
import ShowPage from './pages/ShowPage';
const routes = [
{
path: '/',
component: HomePage
},
{
path: '/blogs',
component: ListPage
},
{
path: '/blogs/create',
component: CreatePage
},
{
path: '/blogs/edit',
component: EditPage
},
{
path: '/blogs/:id',
component: ShowPage
}
];
export default routes;
(순서대로 내려오면서 보기 때문에 router 순서가 중요)

ShowPage.js
import { useParams } from "react-router"; //가져올 수 있다
const ShowPage = () => {
const { id } = useParams();
console.log(id);
return <div>Show Page</div>;
}
export default ShowPage;
36 블로그 db에서 받아와서 화면에 보여주기
db에다 이 id를 가진 블로그의 데이터를 요청해보자

ShowPage.js
import { useParams } from "react-router";
import axios from 'axios';
import { useEffect, useState } from "react";
import LoadingSpinner from "../components/LoadingSpinner";
const ShowPage = () => {
const { id } = useParams();
const [post, setPost] = useState(null);
const [loading, setLoading] = useState(true); //처음에 시작하자마자는 로딩이 되고 있고
const getPost = (id) => { //db에 요청을 보내는 함수
axios.get(`http://localhost:3001/posts/${id}`).then((res) => {
setPost(res.data);
setLoading(false);
})
};
useEffect(() => {
getPost(id);
}, []); //요청은 한번만 보낼거기 때문에 빈 배열 (?)
if (loading) {
return <LoadingSpinner />
}
return ( //아니면은 ~. loading일때는 여기까지 못 오죠?
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
);
}
export default ShowPage;
http://localhost:3000/blogs/2

37 의존성 배열
useEffect(() => {
getPost(id);
});
useEffect() 함수 : 리액트 컴포넌트가 렌더링될 때마다 특정 작업(getPost)을 실행할 수 있도록 하는 Hook.
useEffect(() => {
getPost(id);
}, []);
빈 배열을 넣으면, ShowPage함수가 실행될 때 첫 한번만 실행
useEffect(() => {
getPost(id);
}, [id]);
빈 배열이 아니면, id가 변경될 때마다 실행 -> 의존성 배열
import { useParams } from "react-router";
import axios from 'axios';
import { useEffect, useState } from "react";
import LoadingSpinner from "../components/LoadingSpinner";
import { useHistory } from 'react-router'; //추가가
const ShowPage = () => {
const { id } = useParams();
const [post, setPost] = useState(null);
const [loading, setLoading] = useState(true);
const history = useHistory(); //추가
const getPost = (id) => {
axios.get(`http://localhost:3001/posts/${id}`).then((res) => {
setPost(res.data);
setLoading(false);
})
};
useEffect(() => {
console.log('hello') //추가
getPost(id);
}, [id]); //의존성 배열
if (loading) {
return <LoadingSpinner />
}
return (
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
<button onClick={() => history.push('/blogs/2')}>Click</button> {/* 추가 */}
</div>
);
}
export default ShowPage;
38 블로그 리스트에 링크 연결
Card 눌렀을 때 EditPage로 연결되는 게 아닌 맞는 블로그 페이지로 링크를 연결
ListPage.js
import axios from 'axios';
import { useState, useEffect } from 'react';
import Card from '../components/Card';
import { Link } from 'react-router-dom';
import { useHistory } from 'react-router';
import LoadingSpinner from '../components/LoadingSpinner';
const ListPage = () => {
const history = useHistory();
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const getPosts = () => {
axios.get('http://localhost:3001/posts').then((response) => {
setPosts(response.data);
setLoading(false);
})
}
const deleteBlog = (e, id) => {
e.stopPropagation();
axios.delete(`http://localhost:3001/posts/${id}`).then(() => {
setPosts(prevPosts => prevPosts.filter(post => post.id !== id))
});
};
useEffect(() => {
getPosts();
}, []);
const renderBlogList = () => {
if (loading) {
return (
<LoadingSpinner />
);
}
if (posts.length === 0) {
return (<div>No blog posts found</div>);
}
return posts.map(post => {
return (
<Card
key={post.id}
title={post.title}
onClick={() => history.push(`/blogs/${post.id}`)} //이 부분
>
<div>
<button
className="btn btn-danger btn-sm"
onClick={ (e) => deleteBlog(e, post.id)}
>
Delete
</button>
</div>
</Card>
);
})
};
return (
<div>
<div className="d-flex justify-content-between">
<h1>Blogs</h1>
<div>
<Link to="/blogs/create" className="btn btn-success">
Create New
</Link>
</div>
</div>
{renderBlogList()}
</div>
);
};
export default ListPage;
('/blogs/edit' 에서 `/blogs/${post.id}` 로 변경)
39 블로그 생성된 시간 추가
db에 title, body, id + 생성된 시간 추가 !!
BlogForm.js
const onSubmit = () => {
axios.post('http://localhost:3001/posts', {
title: title,
body: body,
createdAt: Date.now()
}).then(() => {
history.push('/blogs');
})
};
ShowPage.js
import { useParams } from "react-router";
import axios from 'axios';
import { useEffect, useState } from "react";
import LoadingSpinner from "../components/LoadingSpinner";
const ShowPage = () => {
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]);
const printDate = (timestamp) => {
return new Date(timestamp).toLocaleString();
}
if (loading) {
return <LoadingSpinner />
}
return (
<div>
<h1>{post.title}</h1>
<small class="text-muted">
Created At: {printDate(post.createdAt)}
</small>
<hr />
<p>{post.body}</p>
</div>
);
}
export default ShowPage;'Frontend > 프로젝트로 배우는 React.js' 카테고리의 다른 글
| 섹션 7. 블로그 리스트 페이지 수정 (2) | 2023.12.05 |
|---|---|
| 섹션 6. 블로그 수정 페이지 (1) | 2023.11.30 |
| Axios Error: Network Error (0) | 2023.11.29 |
| 섹션 4. 블로그 리스트 (1) | 2023.11.26 |
| 섹션 3. React Router로 페이지 추가하기 (0) | 2023.11.06 |