Next.js - useActionState

윤스타·2024년 6월 18일

Next.js

목록 보기
6/9
post-thumbnail

Next.js - useActionState

useActionState()

Next.js 13에서 도입된 React 훅 중 하나로, 서버 액션의 상태를 관리하는 데 사용된다. 이 훅은 서버 액션의 상태를 추적하고, 이를 통해 액션이 실행 중인지, 완료되었는지, 또는 오류가 발생했는지를 쉽게 확인할 수 있게 해준다.(원래는 react-dom에서 useFormState를 import하여 사용하였지만 변경되었다.)

2024-06-18기준 아직 import { useFormState } from "react-dom"; 이렇게 사용해야한다.

  • 두 가지 값이 필요하다.
    1. 양식이 제출될 때 최종적으로 트리거되어야 할 함수
    2. 첫 번째 인자가 실행되지 않았을 때 사용할 초기 FormState
  • useState()처럼 배열로 받는다. const [state, formAction] = useActionState(formAction, {});
import PostForm from "@/components/postForm";
import { storePost } from "@/lib/posts";
import { redirect } from "next/navigation";

export default function NewPostPage() {
  async function createPost(prevState, formData) {
    "use server";
    const title = formData.get("title");
    const image = formData.get("image");
    const content = formData.get("content");

    let errors = [];

    if (!title || title.trim().length === 0) {
      errors.push("Title is required");
    }

    if (!content || content.trim().length === 0) {
      errors.push("Content is required");
    }

    if (!image) {
      errors.push("Image is required");
    }

    if (errors.length > 0) {
      return { errors };
    }

    await storePost({
      imageUrl: "",
      title,
      content,
      userId: 1,
    });

    redirect("/feed");
  }

  return <PostForm action={createPost} />;
}
// 예전 코드
import { useFormState } from "react-dom";

// 현재 코드
"use client";

import React from "react";
import FormSubmit from "./formSubmit";

import { useFormState } from "react-dom";

export default function PostForm({ action }) {
  const [state, formAction] = useFormState(action, {});

  return (
    <>
      <h1>Create a new post</h1>
      <form action={formAction}>
        <p className="form-control">
          <label htmlFor="title">Title</label>
          <input type="text" id="title" name="title" />
        </p>
        <p className="form-control">
          <label htmlFor="image">Image URL</label>
          <input
            type="file"
            accept="image/png, image/jpeg"
            id="image"
            name="image"
          />
        </p>
        <p className="form-control">
          <label htmlFor="content">Content</label>
          <textarea id="content" name="content" rows="5" />
        </p>
        <p className="form-actions">
          <FormSubmit />
        </p>
        {state.errors && (
          <ul className="form-errors">
            {state.errors.map((error) => (
              <li key={error}>{error}|</li>
            ))}
          </ul>
        )}
      </form>
    </>
  );
}
profile
사이버 노트

0개의 댓글