codinghatso

Learn Next.js 제 12장 : Mutating Data 본문

WEB/Next.js

Learn Next.js 제 12장 : Mutating Data

hatso 2025. 3. 12. 00:45

-ai를 사용해 개념정리 했음을 공지합니다.-

 

invoices page에서 invoices 생성, 업데이트 및 삭제 기능을 추가하는 작업을 진행할 것이다.


이번 장에서 배울 내용

* React Server Actions란 무엇이며, 이를 사용하여 데이터를 변경하는 방법입니다.
* 양식 및 서버 구성 요소 작업 방법.
* 현지인과 협력하는 모범 사례 FormData 객체, 유형 검증 포함.
* 클라이언트 캐시를 다시 검증하는 방법 revalidatePath API.
* 특정 ID로 동적 경로 세그먼트를 만드는 방법.

 

📌 React Server Actions 정의

React Server ActionsNext.js에서 서버에서 직접 실행할 수 있는 비동기 함수를 의미해요.
이를 사용하면 클라이언트에서 서버로 데이터를 보낼 때 API 경로 없이 직접 서버 로직을 실행할 수 있음.


✅ React Server Actions의 특징

서버에서 실행되므로 보안성이 높음 (클라이언트에 노출되지 않음)
API 엔드포인트 없이 바로 서버에서 데이터베이스 작업 가능
클라이언트-서버 간의 데이터 전송을 간소화
폼 제출, 데이터 저장, DB 업데이트 등을 쉽게 구현 가능


✅ 간단한 예제

📌 기존 API 방식

기존 방식에서는 클라이언트에서 API 요청을 보내고, 서버에서 처리해야 했음.

// API 요청 방식 (기존)
async function handleSubmit(data) {
  await fetch('/api/save', {
    method: 'POST',
    body: JSON.stringify(data),
  });
}

📌 Server Actions 방식

이제 API 없이 서버에서 직접 실행 가능.

"use server"; // 서버에서 실행되는 함수임을 명시

export async function saveData(data) {
  // 여기서 DB 저장 등 서버 로직 실행 가능
  console.log("서버에서 실행됨:", data);
}
// 클라이언트에서 Server Actions 호출
"use client";

import { saveData } from "@/app/actions";

export default function Form() {
  async function handleSubmit(formData) {
    await saveData(formData); // API 없이 서버 함수 직접 실행
  }

  return (
    <form action={handleSubmit}>
      <input name="name" type="text" />
      <button type="submit">저장</button>
    </form>
  );
}

✅ 결론

서버에서 직접 실행되는 함수
API 없이 클라이언트에서 서버로 데이터를 보낼 수 있음
보안성이 높고, 코드가 간결해짐
폼 제출, DB 업데이트 등에 활용 가능

🚀 즉, Server Actions은 "Next.js에서 서버 로직을 쉽게 실행할 수 있도록 하는 새로운 방법"! 😊


서버 작업 사용의 한 가지 이점은 무엇입니까?라는 퀴즈가 있는데 

정답은 점진적 향상이었고.

이유는 이를 통해 사용자는 양식의 JavaScript가 아직 로드되지 않았거나 로드되지 않은 경우에도 양식과 상호 작용하여 데이터를 제출할 수 있다는 것입니다.

formData 정상 작동 확인

 

@/app/ui/invoice/edit-form.tsx

코드를 보다가 작동원리가 궁금해서 정리해보았다. 참고하자.

📌 코드 분석: updateInvoice.bind(null, invoice.id);

const updateInvoiceWithId = updateInvoice.bind(null, invoice.id);
return <form action={updateInvoiceWithId}>

이 코드의 핵심은 .bind()를 사용하여 updateInvoice 함수에 invoice.id를 미리 전달하는 것이에요.


✅ .bind()의 역할

updateInvoice.bind(null, invoice.id);
  • .bind()는 함수의 this 값을 고정하고, 미리 일부 인수를 설정하는 메서드.
  • 여기서 null을 전달하는 이유는 this를 사용하지 않기 때문.
  • invoice.id를 첫 번째 인수로 미리 설정하여, 나중에 실행될 때 updateInvoice(invoice.id, ...) 형태가 됨.

예제: .bind() 없이 사용하는 경우

function updateInvoice(id, data) {
  console.log(`Updating invoice ${id} with data`, data);
}

const updateInvoiceWithId = (data) => updateInvoice(invoice.id, data);

이렇게 명시적으로 id를 전달하는 대신, .bind()를 사용하면 코드를 더 간결하게 만들 수 있음.


✅ action={updateInvoiceWithId}의 동작

return <form action={updateInvoiceWithId}>

이제 이 폼을 제출하면 자동으로 updateInvoiceWithId가 실행됨.

  1. <form>의 action 속성에 서버 액션 함수를 전달하면, Next.js는 해당 함수를 서버에서 실행.
  2. 폼 제출 시, 브라우저가 폼 데이터를 updateInvoiceWithId에 전달하고 실행됨.
  3. updateInvoiceWithId는 이미 invoice.id를 포함하고 있으므로, 추가적인 데이터만 인자로 받으면 updateInvoice(invoice.id, formData)가 실행됨.

✅ 최종 결론

.bind(null, invoice.id) → updateInvoice 함수에 invoice.id를 미리 전달
action={updateInvoiceWithId} → 폼 제출 시 해당 함수가 자동 실행되어 송장 데이터 업데이트
Next.js의 Server Actions를 활용하여, API 없이 서버에서 바로 데이터베이스 업데이트 가능

🚀 즉, 이 코드는 "특정 송장의 데이터를 수정하는 폼을 간결하게 만들고, 서버에서 실행되도록 연결하는 역할"을 함! 😊


📌 Next.js에서 동적 경로를 활용한 송장 관리

1️⃣ 동적 경로 생성 → id를 동적 세그먼트로 사용하여 개별 송장 페이지 생성 (/dashboard/invoices/[id]).
2️⃣ 송장 ID 읽기 → useParams()를 이용해 URL에서 id 값을 가져옴.
3️⃣ 데이터베이스에서 송장 조회 → id를 기반으로 특정 송장 데이터를 불러옴.
4️⃣ 양식 자동 입력 → 불러온 데이터를 폼에 미리 채워 사용자가 쉽게 수정 가능.
5️⃣ 송장 데이터 업데이트 → 변경된 데이터를 데이터베이스에 저장하고, revalidatePath()를 통해 최신 상태로 반영.

🚀 이 과정을 통해 특정 송장을 조회하고, 수정 후 즉시 반영할 수 있어 더 편리한 데이터 관리가 가능해집니다! 😊

 

최종적으로 이번 챕터에서 배운 것은 server action에 관한 개념 정리와 동적 경로 생성을 통해 next.js 에서 CRUD 구현이다.

lib의 자식파일은 action.tsx에서 CRUD의 동작을 정의한다.

TypeScript의 Zod 검증 라이브러리를 사용, actions.ts 파일에서 Zod를 가져와 폼 개체의 모양과 일치하는 스키마를 정의합니다. 이 스키마는 데이터베이스에 저장하기 전에 formData를 검증합니다. 즉 검증도 하고

revalidatePath()로 데이터 갱신도 하고.

redirect()로 리디렉션도 한것이다.

마지막으로 UI에서 action은 호출할 수 있도록 구현하면 끝이다.

Comments