Skip to main content

ZOD

假設 API 提供以下的資料結構:

[
{
"id": 1,
"memberId": 1,
"items": [
{
"productId": 3,
"quantity": 1
}
]
},
{
"id": 2,
"memberId": 2,
"items": [
{
"productId": 4,
"quantity": 2
},
{
"productId": 5,
"quantity": 1
}
]
}
]
import { useForm, Controller } from "react-hook-form";

const { control, handleSubmit } = useForm();

<Controller
control={control}
name={`items.${index}.quantity`} // 對應陣列的索引
render={({ field }) => <input {...field} type="number" placeholder="數量" />}
/>;

使用 ZOD 驗證結構

定義 Schema

使用 ZOD 定義資料結構的驗證規則:

import { z } from "zod";

const itemSchema = z.object({
productId: z.number(),
quantity: z.number().min(1, "數量必須至少為 1"),
});

const formSchema = z.object({
items: z.array(itemSchema),
});

結合 react-hook-form 和 ZOD

配合 zodResolveruseForm,將 Schema 應用到表單:

import { zodResolver } from "@hookform/resolvers/zod";

const { control, handleSubmit } = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
items: data[0].items, // 初始化第一筆資料
},
});

const onSubmit = (values) => {
console.log(values);
};

以下是整合 react-hook-form 與 ZOD 的完整程式碼:

import React from "react";
import { useForm, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";

const itemSchema = z.object({
productId: z.number(),
quantity: z.number().min(1, "數量必須至少為 1"),
});

const formSchema = z.object({
items: z.array(itemSchema),
});

const App = () => {
const { control, handleSubmit } = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
items: [
{ productId: 3, quantity: 1 },
{ productId: 4, quantity: 2 },
],
},
});

const onSubmit = (values) => {
console.log(values);
};

return (
<form onSubmit={handleSubmit(onSubmit)}>
{Array(2)
.fill(0)
.map((_, index) => (
<Controller
key={index}
control={control}
name={`items.${index}.quantity`}
render={({ field }) => (
<input
{...field}
type="number"
placeholder={`數量 ${index + 1}`}
/>
)}
/>
))}
<button type="submit">提交</button>
</form>
);
};

export default App;