๊ทธ๋์ ๋ฐฐ์ ๋ Hook์ ์ด์ฉํด ๊ณผ์ ๋ฅผ ํธ๋ ํ์์ ๊ณผ์ ๋ฅผ ์งํํ๋ค.
//์ค์น ๋ฐฉ๋ฒ
npm i -g json-server
//์๋ฒ ์คํ
cd data
json-server --watch data.json --port 3001
--port 3001
๋ผ๋ ์ต์
์ ๋ถ์ฌ์ค 3001๋ฒ ํฌํธ์ ์๋ฒ๋ฅผ ์ด์ด์ค๋ค. (์ต์
์ ์ฃผ์ง ์์ผ๋ฉด ์๋์ผ๋ก 3000๋ฒ ํฌํธ๋ก ์ด์ด์ฃผ๊ธฐ ๋๋ฌธ)sudo npm install
๊ทธ๋ฅ npm install
์ ํ๋ ๊ถํ์ด ์์ด ์ค๋ฅ๊ฐ ๋ฌ๋ค.
sudo
๋ฅผ ์์ ๋ถ์ฌ ์ฃผ๋ฉด ๊ด๋ฆฌ ๊ถํ์ ์ค๋ค๋ ๋ป์ด๋ค.
ํํ ์ปดํจํฐ ํ๋ก๊ทธ๋จ์ด ์ ์ ๋ ๋ ๊ด๋ฆฌ์ ๋ชจ๋๋ก ์คํ ํ๊ธฐ
์ ๋น์ทํ ๋งฅ๋ฝ ๊ฐ๋ค.
http://localhost:3000/blogs/1
์์
1
์ ๋์ ํ๋ผ๋ฏธํฐ์ด๋ค.
์ฌ์ฉ ์ npm install react-router-dom
์ค์น๋ฅผ ๋จผ์ ํด ์ฃผ์ด์ผ ํ๋ค.
์ค์น ํ
import { useParams } from "react-router-dom";
.
.
.
const id = useParams();
console.log(id) // { id : 1}
useParams()๋ ๊ฐ์ฒด์ธ String ํ์
์ ๋ฐํํ๋ค.
๊ทธ๋์ ๊ตฌ์กฐ ๋ถํด ํ ๋น์ผ๋ก ์ ๋ฌํ ์ ์๊ณ ์ด๋ฅผ fetch๋ฅผ ์ด์ฉํด ์ฌ์ฉํ ์ ์๋ค.
// ๊ตฌ์กฐ๋ถํด ํ ๋น
const { id: blogId } = useParams()
// useFetch๋ Custom Hook์ด๋ค.
// ๋ค์ ํ๋ผ๋ฏธํฐ๋ฅผ ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด์ ์ด์ฉํด ๋ณ๊ฒฝํด ์ค ์ ์๋ค.
const [blog, isPending, error] = useFetch(`http://localhost:3001/blogs/${blogId}`)
useParams()์ ๋ง์ฐฌ๊ฐ์ง๋ก npm install react-router-dom
์ค์น๋ฅผ ๋จผ์ ํด ์ฃผ์ด์ผ ํ๋ค.
import { useNavigate } from "react-router-dom";
.
.
.
const navigate = useNavigate();
// ํด๋น ๋ฒํผ ํด๋ฆญ ์ home์ผ๋ก ์ด๋ํ๋ค.
const handleDeleteClick = () => {
// ์ธ์๋ก ์ด๋ํ ๊ฒฝ๋ก๋ฅผ ์์ฑํด ์ค๋ค.
navigate('/')
}
navigate(1)
,navigate(-1)
๋ฅผ ์ด์ฉํด ๋ค์ ๊ฒฝ๋ก, ์ด์ ๊ฒฝ๋ก๋ก ์ด๋ํ ์ ์๋ค.(์๋ ๊ฒ ๋ก)
//BlogDetail.js
const { id: blogId } = useParams()
const [blog, isPending, error] = useFetch(`http://localhost:3001/blogs/${blogId}`)
const [isLike, setIsLike] = useState(false);
const navigate = useNavigate()
const handleDeleteClick = () => {
fetch(`http://localhost:3001/blogs/${blogId}`, {
method: 'DELETE'
})
.then(() => {
navigate('/')
window.location.reload();
})
.catch((err) => console.log(err))
console.log('delete!');
}
const handleLikeClick = () => {
let payload = {
...blog,
likes: !isLike ? blog.likes + 1 : blog.likes - 1
}
fetch(`http://localhost:3001/blogs/${blogId}`, {
method: 'PATCH',
headers: {'Content-Type':'application/json'},
body: JSON.stringify(payload)
})
.then(() => {
setIsLike((prev) => !prev)
})
.catch(err => console.log(err))
}
.
.
.
<button onClick={handleLikeClick}>
{isLike ? "โค๏ธ" : "๐ค"}
</button>
//CreateBlog.js
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
const [author, setAuthor] = useState('๊น์ฝ๋ฉ');
const navigate = useNavigate()
const handleSubmit = (e) => {
e.preventDefault();
const payload = {
title,
body,
author,
likes: 0,
};
fetch(`http://localhost:3001/blogs`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
.then(() => {
navigate('/')
window.location.reload();
})
.catch((err) => console.log(err))
console.log(e.type);
}
then
์ ์ฌ์ฉํด์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.window.location.reload()
๋ฅผ ํด์ ์๋์ผ๋ก ์๋ก๊ณ ์นจ์ด ๋๋๋ก ํ๋ค.๊ณผ์ ๋ฅผ ์ ๋ถ ์๋ฃํ์ง ๋ชปํด ์์ฑํ์ง๋ ๋ชปํ์ง๋ง
์ด๋ฒ ๊ณผ์ ๋ฅผ ํตํด ๋ชฐ๋๋ ๋ถ๋ถ๋ ์๊ฒ ๋์๊ณ
์๋ฒ์ ์์ฒญ ๋ณด๋ด๋ ๋ถ๋ถ์ ์์ผํ๊ฒ ์๊ฐํ๋๊ฑฐ ๊ฐ๋ค.
์ด๋ฒ ๊ธฐํ์ ๊ทธ ๋ถ๋ถ์ ๋ณด์ถฉํ๊ฒ ๋ ๊ณ๊ธฐ๊ฐ ๋ ๊ฑฐ ๊ฐ๋ค.