React Academy · บทเรียน

ฟอร์มปลอดภัยด้านชนิดข้อมูลและสัญญาผลตอบกลับ API

ใช้ Zod เพื่ออนุมานชนิด TypeScript จากสคีมา และตรวจสอบทั้งข้อมูลฟอร์มและผลตอบกลับจาก API

บทเรียน 4 จาก 413 ขั้นตอน

ฟอร์มปลอดภัยด้านชนิดข้อมูลและสัญญาผลตอบกลับ API เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดรูปแบบข้อมูลที่ปลอดภัยด้านชนิดจึงสำคัญ

แบบฟอร์มและการตอบกลับของเอพีไอเป็นขอบเขตที่ข้อมูลจากแหล่งซึ่งไม่อาจไว้วางใจเข้าสู่แอปพลิเคชันของคุณ ซอดช่วยให้คุณกำหนดสคีมาที่ทั้งตรวจสอบขณะทำงานและอนุมานชนิด TypeScript ได้

พื้นฐานสคีมาของซอด

กำหนดสคีมาด้วยเอพีไอแบบต่อเนื่องของซอด ใช้ z.infer<typeof schema> เพื่อดึงชนิด TypeScript ออกมา

import { z } from 'zod';

const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1).max(100),
  email: z.string().email(),
  age: z.number().int().min(0).max(150).optional(),
  role: z.enum(['admin', 'user', 'guest']),
});

type User = z.infer<typeof UserSchema>;
// { id: string; name: string; email: string; age?: number; role: 'admin'|'user'|'guest' }

React Hook Form พร้อมตัวแก้ไขของซอด

ผสานสคีมาของซอดเข้ากับแบบฟอร์มฮุกของรีแอ็กต์เพื่อการตรวจสอบแบบฟอร์มที่ปลอดภัยด้านชนิด โดย TypeScript จะทราบรูปแบบของข้อมูลและข้อผิดพลาดในแบบฟอร์ม

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';

const LoginSchema = z.object({
  email: z.string().email('Invalid email'),
  password: z.string().min(8, 'At least 8 characters'),
});
type LoginData = z.infer<typeof LoginSchema>;

function LoginForm() {
  const { register, handleSubmit, formState: { errors } } = useForm<LoginData>({
    resolver: zodResolver(LoginSchema),
  });

  const onSubmit = (data: LoginData) => {
    // data is LoginData — fully typed, already validated
  };
}

การตรวจสอบการตอบกลับของเอพีไอ

แยกวิเคราะห์การตอบกลับของเอพีไอด้วยซอดเพื่อจับความไม่ตรงกันของรูปแบบข้อมูลที่ขอบเขต หากเอพีไอส่งข้อมูลที่ไม่คาดคิด คุณจะได้รับข้อผิดพลาดโดยละเอียดแทนที่แอปจะหยุดทำงานขณะรันลึกเข้าไปในคอมโพเนนต์

async function fetchUser(id: string): Promise<User> {
  const res = await fetch(`/api/users/${id}`);
  const json = await res.json();
  return UserSchema.parse(json); // throws ZodError if shape is wrong
}

การแยกวิเคราะห์อย่างปลอดภัยเพื่อจัดการข้อผิดพลาดอย่างเหมาะสม

ใช้ schema.safeParse() เพื่อรับออบเจ็กต์ผลลัพธ์แทนการโยนข้อผิดพลาด เหมาะอย่างยิ่งสำหรับการตรวจสอบแบบฟอร์มที่ต้องการแสดงข้อผิดพลาดให้ผู้ใช้เห็น

const result = UserSchema.safeParse(formData);
if (!result.success) {
  const errors = result.error.flatten().fieldErrors;
  // { name: ['Must be at least 1 character'], email: ['Invalid email'] }
  return errors;
}
const user = result.data; // User — fully typed

ยูเนียนแบบจำแนกด้วย Zod

ใช้ z.discriminatedUnion เพื่อจำลองผลลัพธ์จาก API ที่มีรูปแบบแตกต่างกันตามแฟล็กว่าสำเร็จหรือเกิดข้อผิดพลาด

const ApiResponse = z.discriminatedUnion('ok', [
  z.object({ ok: z.literal(true), data: UserSchema }),
  z.object({ ok: z.literal(false), error: z.string(), code: z.number() }),
]);

type ApiResult = z.infer<typeof ApiResponse>;
// { ok: true; data: User } | { ok: false; error: string; code: number }

การแปลงข้อมูลด้วย Zod

ใช้ .transform() เพื่อแปลงชนิดหรือปรับรูปข้อมูลระหว่างการแยกวิเคราะห์ เช่น แปลงสตริงวันที่เป็นออบเจ็กต์ Date

const DateSchema = z.string().transform(s => new Date(s));
// Input: '2024-01-15' → Output: Date object

const EventSchema = z.object({
  title: z.string(),
  date: z.string().pipe(z.coerce.date()),
});
type Event = z.infer<typeof EventSchema>;
// { title: string; date: Date }

การนำสคีมากลับมาใช้ใหม่

สร้างสคีมาสำหรับการสร้างและการอัปเดตจากสคีมาพื้นฐาน เพื่อหลีกเลี่ยงการเขียนซ้ำ

const UserSchema = z.object({ name: z.string(), email: z.string().email() });

// For creation: add password
const CreateUserSchema = UserSchema.extend({ password: z.string().min(8) });

// For update: all fields optional
const UpdateUserSchema = UserSchema.partial();

type CreateUser = z.infer<typeof CreateUserSchema>;
type UpdateUser = z.infer<typeof UpdateUserSchema>;

การดำเนินการฝั่งเซิร์ฟเวอร์ด้วย Zod

ตรวจสอบข้อมูลฟอร์มในการดำเนินการฝั่งเซิร์ฟเวอร์ของ Next.js ด้วย Zod ก่อนเข้าถึงฐานข้อมูล

async function createPost(formData: FormData) {
  'use server';
  const schema = z.object({ title: z.string().min(3), body: z.string().min(10) });
  const result = schema.safeParse(Object.fromEntries(formData));
  if (!result.success) return { errors: result.error.flatten().fieldErrors };
  await db.post.create({ data: result.data });
  revalidatePath('/blog');
  redirect('/blog');
}

สคีมาที่ใช้ร่วมกันระหว่างส่วนหน้าและส่วนหลัง

ส่งออกสคีมา Zod จากแพ็กเกจที่ใช้ร่วมกัน เพื่อให้ส่วนหน้าและส่วนหลังใช้ตรรกะการตรวจสอบเดียวกัน โดยมีสคีมาเดียวเป็นแหล่งข้อมูลจริงเพียงแห่งเดียว

// packages/schemas/src/user.ts
export const CreateUserSchema = z.object({ ... });
export type CreateUser = z.infer<typeof CreateUserSchema>;

// Frontend imports:
import { CreateUserSchema, CreateUser } from '@company/schemas';
// Backend imports:
import { CreateUserSchema } from '@company/schemas';

ข้อความข้อผิดพลาดของ Zod

กำหนดข้อความข้อผิดพลาดแยกตามฟิลด์ เพื่อให้ประสบการณ์ผู้ใช้ดีขึ้น โดยตัวแก้ไขจะส่งข้อความเหล่านี้ไปแสดงในส่วนแสดงข้อผิดพลาดของฟอร์มโดยอัตโนมัติ

const RegistrationSchema = z.object({
  username: z.string()
    .min(3, 'Username must be at least 3 characters')
    .max(20, 'Username cannot exceed 20 characters')
    .regex(/^[a-z0-9_]+$/, 'Only lowercase letters, numbers, and underscores'),
});

ตรวจสอบความเข้าใจ

z.infer ให้สิ่งใดใน TypeScript

สรุปทบทวน

กำหนดสคีมา Zod เพียงครั้งเดียว แล้วใช้ z.infer เพื่อสร้างชนิดข้อมูล TypeScript ใช้ zodResolver ใน React Hook Form เพื่อการตรวจสอบชนิดข้อมูลอย่างปลอดภัย แยกวิเคราะห์ผลลัพธ์จาก API ด้วย Zod ที่ขอบเขตของระบบ ใช้ safeParse สำหรับข้อผิดพลาดที่แสดงต่อผู้ใช้ และแชร์สคีมาระหว่างส่วนหน้ากับส่วนหลังผ่านแพ็กเกจที่ใช้ร่วมกัน

เริ่มต้นได้ฟรี

เรียนรู้ React ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
88
บทเรียน
324

คำถามที่พบบ่อย

บทเรียน “ฟอร์มปลอดภัยด้านชนิดข้อมูลและสัญญาผลตอบกลับ API” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ฟอร์มปลอดภัยด้านชนิดข้อมูลและสัญญาผลตอบกลับ API” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ฟอร์มปลอดภัยด้านชนิดข้อมูลและสัญญาผลตอบกลับ API”

ใช้ Zod เพื่ออนุมานชนิด TypeScript จากสคีมา และตรวจสอบทั้งข้อมูลฟอร์มและผลตอบกลับจาก API คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ฟอร์มปลอดภัยด้านชนิดข้อมูลและสัญญาผลตอบกลับ API” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม

ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ยูเนียนแบบแยกแยะสำหรับรูปแบบคอมโพเนนต์
  2. ชนิดแบบมีเงื่อนไขและชนิดแบบแมปใน React
  3. คอมโพเนนต์พหุรูปแบบด้วย Prop 'as'
  4. ฟอร์มปลอดภัยด้านชนิดข้อมูลและสัญญาผลตอบกลับ API
← กลับไปที่ React Academy