post 데이터는 서버 컴포넌트에서 fetch를 통해 가져왔기 때문에 revalidateTag를 이용해서 데이터를 업데이트시켜야 했다.
그런데, 클라이언트 함수에서 revalidateTag를 호출했을 때, 에러가 발생함.
const handleSubmit = async () => {
// ...
await fetch(url, { method: "DELETE" });
revalidateTag("comments");
// Invariant: static generation store missing in revalidateTag comments
}
클라이언트 컴포넌트에서 revalidate를 하는 방법을 알아봤다.
"How to revalidate data from the client Component"
이 질문의 답변 내용 중 "revalidate하는 함수를 serverAction으로 만들어라"라는 걸 보고 적용해봤다.
// actions.ts
const deleteComment = async (commentId: string, password: string) => {
"use server";
// host, protocol, url을 구하기
await fetch(url, { method: "DELETE" });
revalidateTag("comments");
}
// DeleteCommentDialog.tsx 중
const handleAction = async (formData: FormData) => {
// ...
await deleteComment(commentId, password);
}
알게된 내용
서버 액션은 서버 컴포넌트에서만 사용이 가능한 줄 알았지만, 아니었다.
하긴, 서버 컴포넌트도 어떻게 보면 서버 함수일텐데, 클라이언트 컴포넌트의 자식 컴포넌트로 렌더링을 할 수 있으니까.
비밀번호를 어떻게 전달할 것인가?
DELETE 메서드는 body를 포함할 수는 있지만, 실제로 body를 사용하는 것을 권장하진 않는다고 한다. (경우에 따라서 body를 사용할 수 없는 케이스도 있기 때문)
그렇다면, 어떻게 비밀번호를 포함해서 전달할까?
-> QueryString에 비밀번호를 포함시켜서 전달하도록 함
supabase로 삭제 요청을 보냈을 때, 실제로 삭제되었는지 판단하려면?
eq 메서드로 id, password를 전달해서, 삭제요청을 보냈는데 id와 password가 일치하지 않는 케이스를 판단하려면 count를 활용할 수 있다.
delete의 옵션에 count 로직을 어떻게 수행할 지 결정할 수 있다.
count 옵션이 없으면 count가 null로 반환되고, 있으면 실제 삭제된 row의 수가 반환된다.
// comments/:id/route.ts
const DELETE = async () => {
// ...
const { count } = await supabase
.from("comments")
.delete({ count: "exact" })
.eq("id", id)
.eq("password", password);
}
encodeURIComponent
함수를 통해 인코딩시키기const encodedPassword = encodeURIComponent(password)
const url = `${protocol}://${host}/api/comments/${commentId}?password=${encodedPassword}`
one-time-code
로 하면, confirm 창이 뜨지 않음.<input
type="password"
autoComplete="one-time-code"
/>
one-time-code
로 설정하기min
메서드를 활용했고, 추후에 다른 조건이 생기면 schema만 수정해주면 될 것 같다.const createCommentSchema = z.object({
name: z.string().min(1),
content: z.string().min(1),
password: z.string().min(1),
});
const handleFormAction = async (formData: FormData) => {
// ...
const data = {
name,
content,
password,
}
const parsedData = createComentSchema.safeParse(data);
if (!parsedData.success) {
alert("입력값을 확인해주세요");
return;
}
};
Dinosaur Game is a fascinating game that you can play anytime, anywhere, without the need for an internet connection, ensuring you are always entertained no matter where you are, whether it's on a long flight, a road trip, or simply in an area with no Wi-Fi.