본문 바로가기
nextjs/next 14 공식 문서 부시기

[next 14 공식문서 부시기] 3.2 Server Actions 활용

by spare8433 2024. 2. 16.

Server Actions 과 데이터 변경


Server Actions서버에서 실행되는 비동기 함수입니다. Server componnentsClient Components 에서 form 제출 및 데이터 변경을 처리하는 데 사용할 수 있습니다.


React use server 지시어를 비동기 함수 상단에 지시문을 배치하여 함수를 Server Actions 으로 표시하거나 별도의 파일 상단에 배치하여 해당 파일의 모든 export 를 Server Actions 으로 사용할 수 있다.


Server Actions은 Next.js caching 과 revalidation 아키텍처와 통합됩니다. Server Actions이 호출될 때 Next.js는 single server roundtrip으로 업데이트된 UI와 새 데이터를 모두 반환할 수 있습니다.


Server Actions은 내부적으로 POST 메서드를 사용하며 이 HTTP 메서드만 해당 작업을 호출할 수 있습니다.


함수 인자 값과 리턴 값의 타입이 정해져 있습니다. Serializable arguments and return values


Server Actions 은 함수이므로 애플리케이션의 어느 곳에서나 재사용할 수 있습니다.



Server Components 에서 Server Action 활용


함수내에서 인라인으로 "use server" 키워드를 사용하거나 모듈 단위에서 "use server" 키워드를 사용하는 두가지 경우 모두 불러와 사용 가능하다.



Client Components 에서 Server Actions 활용

모듈 단위에서 "use server" 키워드를 사용하는 경우만 불러와 사용 가능하다. 또한 Client ComponentsServer ActionProps 로 전달해 사용가능하다.



Form and Server Actions


Server Actions 은 nextjs 에서 비동기 함수를 처리하는 개념이자 방식으로 서버에서 비동기 관련 로직을 처리하기 때문에 여러 장점이 있다. form 요소를 처리하는 경우에도 action 속성에 관련 로직을 처리하는 함수를 Server actions 으로 생성해 전달해 호출할 수 있다.


React는 HTML <form> 요소를 확장하여 Server Actions이 action prop으로 호출될 수 있도록 합니다. 이후 form 이 호출되면 Server actions이 자동으로 FormData 객체를 인자로 받아 처리합니다.


Server Actions<form>으로 제한되지 않으며 이벤트 핸들러, useEffect, third-party libraries<button> 과 같은 기타 form elements에서 호출될 수 있습니다.



상세 설명

  • JavaScript가 아직 로드되지 않았거나 비활성화된 경우에도 form 이 제출됩니다.
  • Client Components에서 Server Actions을 호출하는 formJavaScript가 아직 로드되지 않은 경우 제출을 queue에 넣어 클라이언트 hydration 의 우선 순위를 지정합니다.
  • hydration 이후 form submission 될 때 브라우저가 새로 고쳐지지 않습니다.



// 기본 예제
export default function Page() {
  async function createInvoice(formData: FormData) {
    'use server'

    const rawFormData = {
      customerId: formData.get('customerId'),
      amount: formData.get('amount'),
      status: formData.get('status'),
    }

    // mutate data
    // revalidate cache
  }

  return <form action={createInvoice}>...</form>
}




// useFormState 을 추가해 활용한 예제
import { useFormState } from "react-dom";

export default function Page() {
  async function createInvoice(prevState: { message: string }, formData: FormData) {
    'use server'

    const rawFormData = {
      customerId: formData.get('customerId'),
      amount: formData.get('amount'),
      status: formData.get('status'),
    }
    // const rawFormData = Object.fromEntries(formData.entries())

    return { message:'message' }
    // revalidate cache
  }

  const [state, formAction] = useFormState(createTodo, { message: "" });
  return <form action={createInvoice}>
    ...
    {state?.message}
  </form>
}




Non-form Elements

이벤트 핸들러 및 useEffect와 같은 코드의 다른 부분에서도 Server Actions을 호출할 수 있습니다.



'use client'

import { incrementLike } from './actions'
import { useState } from 'react'

export default function LikeButton({ initialLikes }: { initialLikes: number }) {
  const [likes, setLikes] = useState(initialLikes)

  return (
    <>
      <p>Total Likes: {likes}</p>
      <button
        onClick={async () => {
          const updatedLikes = await incrementLike()
          setLikes(updatedLikes)
        }}
      >
        Like
      </button>
    </>
  )
}




Error Handling

오류가 발생하면 클라이언트에서 가장 가까운 error.js 또는 <Suspense> 경계에 의해 포착됩니다.




Revalidating data


revalidatePath API를 사용하여 서버 작업 내에서 Next.js 캐시의 유효성을 다시 검사할 수 있습니다.



'use server'

import { revalidatePath } from 'next/cache'

export async function createPost() {
  try {
    // ...
  } catch (error) {
    // ...
  }

  revalidatePath('/posts')
}




Redirecting

Server Action 완료 후 redirect API를 활용해 redirect 할 수 있습니다. redirecttry/catch 블록 외부에서 호출되어야 합니다.



Cookies

쿠키 API를 사용하여 서버 작업 내에서 쿠키를 가져오고 설정하고 삭제할 수 있습니다.



'use server'

import { cookies } from 'next/headers'

export async function exampleAction() {
  // Get cookie
  const value = cookies().get('name')?.value

  // Set cookie
  cookies().set('name', 'Delba')

  // Delete cookie
  cookies().delete('name')
}




참고

https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating
https://www.youtube.com/watch?v=dDpZfOQBMaU&t=367s