C.W.K.
Stream
Lesson 02 of 08 · published

Form Action

~20 min · form, action, FormData

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

action prop

가장 단순 form pattern: form 의 action prop 에 Server Action 넘김. Submission 이 form 의 FormData 와 함께 action trigger. Page 가 revalidatePath invalidate 한 거랑 함께 re-render.

FormData 읽기

FormData entry 가 string (또는 file). Typed access 위해 formData.get('name') as string. File 위해 formData.get('avatar') as File 로 type narrow.

.bind() 로 추가 인자 넘기기

Form 안 없는 id 또는 context 자주 넘기고 싶음. .bind(null, id) 사용 — bound 인자가 FormData 앞에 도착. Framework 가 client 한테 action reference 보내기 전에 bound value 안전하게 encrypt.

Code

Form + Server Action·tsx
// app/actions.ts
'use server';
import { revalidatePath } from 'next/cache';

export async function addTodo(formData: FormData) {
  const text = formData.get('text') as string;
  await db.todo.create({ data: { text, done: false } });
  revalidatePath('/todos');
}

// app/todos/page.tsx
import { addTodo } from '@/app/actions';

export default async function TodosPage() {
  const todos = await db.todo.findMany();
  return (
    <>
      <ul>{todos.map(t => <li key={t.id}>{t.text}</li>)}</ul>
      <form action={addTodo}>
        <input name="text" required />
        <button>Add</button>
      </form>
    </>
  );
}
추가 인자 bind·tsx
'use server';
export async function updateTodo(id: string, formData: FormData) {
  const text = formData.get('text') as string;
  await db.todo.update({ where: { id }, data: { text } });
  revalidatePath('/todos');
}

function TodoItem({ todo }: { todo: { id: string; text: string } }) {
  const updateWithId = updateTodo.bind(null, todo.id);
  return (
    <form action={updateWithId}>
      <input name="text" defaultValue={todo.text} />
      <button>Save</button>
    </form>
  );
}

External links

Exercise

Create 와 delete 위해 Server Action 한 개씩 가진 작은 todo app. Delete action 에 todo id 넘기기 위해 .bind 사용.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.