OOS Gallery를 참고하여 작성하였습니다.

액션 함수 예시

export async function editGradient(
  _prevState: any,
  data: FormData,
): Promise<FormResponse> { // 리턴값이 FormResponse (아래 types.ts참고)
  try {
    console.log(data.get("gradient"));
    
    
    const { gradient, projectId } = editGradientSchema.parse({
      gradient: data.get("gradient"),
      projectId: data.get("projectId"),
    });

    await authProject({ projectId });

    await prisma.project.update({
      where: {
        id: projectId,
      },
      data: {
        gradient,
      },
    });

    return {
      status: "success",
      message: "Gradient updated successfully",
    };
  } catch (e) {
    if (e instanceof ZodError) {
      console.log(e);
      return {
        status: "error",
        message: "Invalid form data",
        errors: e.issues.map((issue) => ({
          path: issue.path.join("."),
          message: issue.message,
        })),
      };
    }
    return {
      status: "error",
      message: e.message,
    };
  }
}

type.ts

export type FormResponse =
  | {
      status: 'success';
      message: string;
    }
  | {
      status: 'error';
      message: string;
      errors?: Array<{
        path: string;
        message: string;
      }>;
    }
  | null;
  
  

Zod를 사용하여 양식 스키마 정의

Zod는 종속성이 전혀 없습니다. 즉, 번들 크기를 더 작게 유지하는 데 도움이 되는 독립 실행형 라이브러리입니다. 간결하고 연결 가능한 API 인터페이스가 있습니다. 이렇게 하면 복잡한 데이터 구조를 더 쉽게 만들 수 있습니다. 단순한 유형을 복잡한 데이터 구조로 구성하는 것은 쉽습니다.

// zod를 이용한 타입검사.
export const editProjectSchema = z.object({
  name: z.preprocess(trim, z.string().min(1).max(64), {
    message: "Invalid project name",
  }),
  description: z.preprocess(trim, z.string().min(1).max(1000), {
    message: "Invalid project description",
  }),
  github: z
    .string()
    .transform((v) => getUrlFromString(v))
    .refine((v) => isValidUrl(v), { message: "Invalid GitHub URL" }),
  website: z
    .string()
    .transform((v) => getUrlFromString(v))
    .refine((v) => isValidUrl(v), { message: "Invalid website URL" })
    .optional(),
  projectId: z.string().min(8),
});