ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Next.js 14 / 🔥 Tadak Tadak 🔥] Next.js 14 새로운 기능! Server Actions 알아보자!
    Next.js 2024. 1. 11. 13:55

     

     

    🍎 목차
    1. Server Actions 등장
    2. Server Component 에서 Server Actions 사용하기
    2. Client component에서 Server Actions 사용하기 

     

    1. Server Actions 등장

    Server Actions are asynchronous functions that are executed on the server. They can be used in Server and Client Components to handle form submissions and data mutations in Next.js applications.

     

    Next.js 14 가 나오면서 실험적이었던 기능이었던 Server Actions가 안정화되면서 도입되었습니다.  공식 문서의 본문을 보면  ' 서버 액션은 서버에서 비동기적으로 실행되는 기능이다. 서버 컴포넌트와 클라이언트 컴포넌트에서 폼 제출과 데이터 변형을 하는 데 사용된다. '라고 나와 있습니다. 

     

    Server Actions을 이용해서 로그인 폼과 회원가입 폼을 구현하기에 앞서 간단한 예시로 이해하고 가려고 합니다. 

     

    결론 부터 말하면 server actions 기능을 사용하면 page.tsx (컴포넌트) 안에서 서버 기능까지 전부 구현 가능해집니다. 

     

    1.  Server Component 에서 Server Action 사용하기

     

    먼저 프로젝트에 쓰일 회원가입 form 을 보면 아래와 같습니다.

    사용자의 닉네임, 아이디, 비밀 번호를 입력해야 하는 form 형태입니다. 

     

    <form action={handleSubmit}>
        <div>
          <label htmlFor='name'>닉네임</label>
          <input name='nickname' />
        </div>
        <div>
          <label className={style.inputLabel} htmlFor='id'>
            아이디
          </label>
          <input name='id' />
        </div>
        <div>
          <label className={style.inputLabel} htmlFor='password'>
            비밀번호
          </label>
          <input name='password' />
        </div>
        <button type='submit'>회원가입 폼 제출하기</button>
    </form>

     

     

    form 태그의 경우에는 action이라는 속성을 가지고 있는데 원래 대로 라면 <form action="URL"> 형태로 폼 데이터를 서버로 보낼 때 해당 데이터가 도착할 URL을 명시했었을 겁니다. 

     

    하지만 Next.js 14 에서는 {중괄호}를 열어서 server actions 기능을 쓸 수 있습니다. 

     

    form 을 제출하면 내용을 받아서 DB에 저장하는 API가 필요한데, server actions을 사용하면 따로 api 폴더를 열어서 코드를 짤 필요 없이 page.tsx 안에서 작성할 수 있게 됩니다. 

     

    회원가입을 구현하는 경우이기 때문에, handleSubmit이라는 함수를 만들고 'use server'라고 함수 안에 명시해 주면, 'use server' 아래의 내용은 자동으로 Server API가 됩니다. 

     

    제출 버튼을 눌르면 폼 전송 시 handleSubmit 함수가 실행되게 됩니다.

    이렇게 하게 되면 api 폴더에서 따로 기능을 만들지 않아도 되기 때문에 편리합니다. 

     

    export default function SignupModal() {
      async function handleSubmit(signupFormData) {
        'use server'
    
        console.log(signupFormData)
      }
    
      return (
        <div className={style.modalBackground}>
          <div className={style.modal}>
            <div className={style.modalHeader}>
              <div>회원가입 모달</div>
              <form action={handleSubmit}>
                ...
              </form>
            </div>
          </div>
        </div>
      )
    }

     

     

    ❗️주의할 점은 server actions 용으로 만드는 함수는 항상 async를 붙여줘야 합니다. 안 그러면 

     

    Server actions must be async functions

     

    에러가 뜰 겁니다. 

     

     

     

    이어서 formdata 콘솔 값을 확인해 보면

     

    위와 같이 form 제출 data를 확인할 수 있습니다. 

     

    만약 특정 input 값을 이용하고 싶다면 get 메서드를 사용하면 됩니다. 

    닉네임 값을 알고 사용하고 싶다면  signupFormData.get('nickname') 하여 ea 라는 id 값을 얻을 수 있습니다. 

     

    2.  Client Component에서 Server Actions 사용하기 

     

    로그인 form을 client component를 이용해서 구현해 볼게요! 크게 다를 건 없습니다. 

     

    로그인 폼의 경우에도 form 구조는 회원가입 폼과 유사합니다. 아이디와 비밀번호를 사용자에게 입력 받을 겁니다. 

     

     

     

    <form action={handleSubmit}>
        <div>
          <label className={style.inputLabel} htmlFor='id'>
            아이디
          </label>
          <input name='id' />
        </div>
        <div>
          <label className={style.inputLabel} htmlFor='password'>
            비밀번호
          </label>
          <input name='password' />
        </div>
        <button type='submit'>로그인 하기</button>
    </form>

     

     

    'use client' 를 달아서 페이지를 클라이언트 컴포넌트로 만들어 주고 server actions 부분 함수는 actions로 따로 빼주어야 합니다.

     

    빼주지 않으면 친절하게 에러창이 뜹니다. 

     

     

    // actions.txs
    'use server'
    
    export async function handleSubmit(formData) {
      console.log(formData)
    }
    
    // pages.txs
    'use client'
    
    import { handleSubmit } from './actions'
    import style from './login.module.css'
    
    export default function LoginModal() {
      return (
        <div className={style.modalBackground}>
          <div className={style.modal}>
            <div className={style.modalHeader}>
              <div>로그인 모달</div>
    
              <form action={handleSubmit}>
                ...
              </form>
            </div>
          </div>
        </div>
      )
    }

     

     

    formData도 동일하게 확인이 가능합니다. 

     

     

     

     

    이와 같이 데이터 생성 외에도 수정, 삭제 기능을 만들 때도 컴포넌트 안에서 모든 걸 해결할 수 있습니다. 

    이렇게 되면 서버 API를 따로 만들 필요 없이 거의 모든 기능을 컴포넌트 안에서 개발할 수 있습니다. 

     

    반응형

    댓글

Designed by Tistory.