.env.local
파일을 루트 디렉토리에 생성한다.
해당 파일은 .gitignore
에 포함되어있을 것이다.
// .env.local
NEXT_PUBLIC_API_URL=http://localhost:9999
먼저, NEXT_PUBLIC
을 붙이지 않으면 서버 컴포넌트에서만 작동하며 클라이언트 컴포넌트에서 작동하지 않는다.
그 이유는 NEXT_PUBLIC
을 붙이면 브라우저에서 엑세스할 수 없기 때문이다.
즉 보안을 위해서 꼭 적어주어야 하는 것이다.
이는 공식문서 에서 자세히 확인할 수 있다.
글 수정 및 삭제 버튼은 url 의 id 값을 가져와야한다.
즉 서버 컴포넌트가 아닌 클라이언트 컴포넌트로 작성되어야한다.
// app/Control.tsx
"use client";
import { useParams, useRouter } from "next/navigation";
export function Contorl() {
const { id } = useParams();
const router = useRouter();
return (
<ul>
<li>
<a href="/create">Create</a>
</li>
{id ? (
<>
<li>
<a href={"/update/" + id}>Update</a>
</li>
<li>
<input
type="button"
value="delete"
onClick={() => {
const options = { method: "delete" };
fetch(
`${process.env.NEXT_PUBLIC_API_URL}/topics/${id}`,
options
)
.then(resp => resp.json())
.then(result => {
router.push("/");
router.refresh();
});
}}
/>
</li>
</>
) : null}
</ul>
);
}
url 에 id
값이 있어야만 업데이트, 삭제 버튼이 띄워지도록 만들었다.
따라서 메인 페이지에는 글 생성 버튼인 'create' 만 노출되고, 업데이트와 삭제는 보이지 않는다.
게시글 뷰페이지로 이동하면 아래와 같이 업데이트와 삭제 버튼이 노출된다.
// app/update/[id]/page.tsx
"use client";
import { useParams, useRouter, useSearchParams } from "next/navigation";
import { Result } from "postcss";
import { useEffect, useState } from "react";
export default function Update() {
const [title, setTitle] = useState<string>("");
const [body, setBody] = useState<string>("");
const router = useRouter();
const { id } = useParams();
useEffect(() => {
fetch(`${process.env.NEXT_PUBLIC_API_URL}/topics/${id}`)
.then(resp => resp.json())
.then(result => {
setTitle(result.title);
setBody(result.body);
});
}, []);
return (
<form
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const title = (
e.currentTarget.elements.namedItem("title") as HTMLInputElement
).value;
const body = (
e.currentTarget.elements.namedItem("body") as HTMLInputElement
).value;
const options = {
method: "put",
headers: {
"content-Type": "application/json",
},
body: JSON.stringify({ title, body }),
};
fetch(`http://localhost:9999/topics/${id}`, options)
.then(res => res.json())
.then(result => {
const lastid = result.id;
router.push(`/read/${lastid}`);
router.refresh();
});
}}
>
<p>
<input
name="title"
type="text"
placeholder="title"
value={title}
onChange={e => setTitle(e.target.value)}
/>
</p>
<p>
<textarea
name="body"
placeholder="body"
value={body}
onChange={e => setBody(e.target.value)}
/>
</p>
<p>
<input type="submit" value="update" />
</p>
</form>
);
}
업데이트 페이지
게시글 업데이트 후 -> 업데이트된 게시글 뷰페이지로 이동 및 업데이트된 내용 확인 가능
게시글 삭제 -> 메인페이지로 이동, 목록에 삭제한 게시글 비노출 확인