서버 액션을 써서 form을 제출하고 싶었다.
그리고 정상 제출되면 form의 모든 필드를 비우고 싶었다.
...'싶었다'는 말은 생각처럼 되지 않았다는 뜻이다.

정답은 결국 클라이언트 컴포넌트 로 바꾸기
서버 컴포넌트 좋은 거 맞아...? 라고 할뻔
아무리 검색해도 서버 컴포넌트에서 폼 제출 후 초기화 방법이 없었다.
영어영어 글들을 열심히 영어영어해도 다 "use client" 가 붙어 있었다.
아, 클라이언트 컴포넌트로 만드는 수밖에 없구나!
그래서 나도 붙였는데 클라이언트 컴포넌트에서는 "use server"를 못 쓴다고 에러가 떴다.
... 그래서 action에 걸어놓은 함수를 따로 파일로 뺐다.
import { postComment } from "@/app/comment/_apis/postComment";
import { useRef } from "react";
import { revalidatePath } from "next/cache";
export default function InputForm() {
const formRef = useRef<HTMLFormElement>(null);
return (
<form
ref={formRef}
action={async (formData: FormData) => {
const result = await postComment({ formData });
if (result === 200) {
formRef.current?.reset();
revalidatePath("/comment", "page");
}
}}
>
// ~~~
</form>
);
};
여기서 봐줘야 하는 건 아래 두 가지, 역할은 다음과 같다.
- ref : 제출 후 초기화할 대상으로 설정한다.
- action : 폼이 제출될 때 수행할 동작을 설정한다.
이 친구가 하는 일을 간단하게 말하자면 찜>.<이다.
위의 코드를 예로 들면, 폼 태그에 ref={formRef} 를 써줬기 때문에formRef 라는 변수가 폼 태그를 찜>.<한 것이다.
그래서 앞으로 폼 태그에 이것저것 해주고 싶다면 formRef 에 이것저것 해주면 된다.
그럼 찜콩해준 태그에 실제로 적용이 된다.
그래서 제출 완료 후 폼 태그 값을 다 갈아버리고 싶을 때 formRef.current?.reset(); 을 쓰면 실제로 리셋된다.
기존 "use server" 를 쓰던 함수를 저 postComment 로 뺀 것이다.
폼 데이터 어떻게 넘기지?!...는 이벤트 객체 e 넘길 때 처럼 그냥 formData 로 넘기면 된다.
"use server";
import { $Fetch } from "@/util/fetch";
export const postComment = async ({ formData }: { formData: FormData }) => {
const title = formData.get("title") as string;
const name = formData.get("name") as string;
const content = formData.get("content") as string;
const data = {
title: title,
name: name,
content: content,
};
const now = new Date();
const write_date = new Date(
now.toLocaleString("en-US", { timeZone: "Asia/Seoul" })
)
.toISOString()
.slice(0, 19)
.replace("T", " ");
const dataWithDate = {
...data,
write_date: write_date,
};
const result = await $Fetch({
method: "POST",
url: "comment",
cache: "default",
data: dataWithDate,
});
return result.status;
};
이렇게 해주면 클라이언트 컴포넌트 안에 "use server" 를 쓸 수 있다.
저 $Fetch 는 뭐지? 싶다면 여기로...
문제 없이 POST 요청이 완료됐다면 데이터 캐싱도 지워주고 폼도 지워줘야 하니까 결과의 status 를 반환해준다.
서버 컴포넌트로 해보고 싶었지만... 실패했다!
그래도 클라이언트 컴포넌트 안에 "use server" 쓰는 법을 알았다!