글을 누르고 Update버튼을 누르면 404에러가 발생하는 상황입니다. 해당 글의 update를 구현하려면 app/src/update/[id]/page.js를 만들 것 입니다.
Update는 2가지 기능의 합성이라고 생각하면 쉬울 것 입니다.
1. Create
2. Read
기본적인 구조는 Create가 더 간편하기 때문에 Create의 구조를 가져오겠습니다.
"use client";
import { useRouter } from "next/navigation";
export default functionUpdate() {
const router = useRouter();
return (
<form
onSubmit={async (evt) => {
evt.preventDefault();
const title = evt.target.title.value;
const body = evt.target.body.value;
const resp = await fetch("http://localhost:9999/topics/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ title, body }),
});
const topic = await resp.json();
router.push(`/read/${topic.id}`);
router.refresh();
}}
>
<h2>Update</h2>
<p>
<input type="text" name="title" placeholder="title" />
</p>
<p>
<textarea name="body" placeholder="body"></textarea>
</p>
<p>
<input type="submit" value="create" />
</p>
</form>
);
}
Update에는 원본이 적혀있어야 하기 때문에 Read 기능도 가지고 있는 것입니다.
Read페이지를 열어보았더니 현재 서버 컴포넌트로 사용이 불가능한 상황입니다.
"use client";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
export default function Update(props) {
const router = useRouter();
const [title, setTitle] = useState("");
const [body, setBody] = useState("");
const id = props.params.id;
async function refresh() {
const resp = await fetch(`http://localhost:9999/topics/${id}`);
const topic = await resp.json();
setTitle(topic.title);
setBody(topic.body);
}
useEffect(() => {
refresh();
}, []);
return (
<form
onSubmit={async (evt) => {
evt.preventDefault();
const title = evt.target.title.value;
const body = evt.target.body.value;
const resp = await fetch(`http://localhost:9999/topics/${id}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ title, body }),
});
const topic = await resp.json();
router.push(`/read/${topic.id}`);
router.refresh();
}}
>
<h2>Update</h2>
<p>
<input
type="text"
name="title"
placeholder="title"
onChange={(e) => setTitle(e.target.value)}
value={title}
/>
</p>
<p>
<textarea
name="body"
palceholder="body"
onChange={(e) => setBody(e.target.value)}
value={body}
></textarea>
</p>
<p>
<input type="submit" value="update" />
</p>
</form>
);
}
"use client"; : 클라이언트 컴포넌트로 바꿔야하기에 사용합니다.const [title, setTitle] = useState("");: 글을 타이틀과 바디 폼에 넣기 위해 state만들었습니다. 그 후 각각의 value값에 값을 줍니다.<input type="text" name="title" placeholder="title" onChange={(e) => setTitle(e.target.value)} value={title} />method: "PATCH" : POST가 아니라 수정을 할때는 PUSH나 PATCH로 코딩해야합니다.이렇게 해서 웹페이지를 통해 글을 수정할 때, 글의 제목과 내용의 첫글자를 대문자로 입력해도 표시되는 것은 소문자였습니다. 글 목록을 가져올 때 cache: HIT 인 것을 볼 수 있습니다. 그래서 상세보기 페이지에서 cach: : “no-store” 를 설정하였습니다.
export default async function Read(props) {
const resp = await fetch(`http://localhost:9999/topics/${props.params.id}`, {
cache: "no-store",
});
const topic = await resp.json();
return (
<>
<h2>{topic.title}</h2>
{topic.body}
</>
);
}