폼 관리: react-hook-form + zod
비제어 컴포넌트 기반으로 불필요한 리렌더링을 최소화하고, zod로 유효성을 검증합니다.
tsx
import { z } from 'zod';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
const productSchema = z.object({
name: z.string().min(1, '이름을 입력해주세요'),
price: z.number().min(0, '0 이상이어야 합니다'),
});
type ProductSchema = z.infer<typeof productSchema>;
function ProductForm() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<ProductSchema>({
resolver: zodResolver(productSchema),
});
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<input {...register('name')} />
{errors.name && <span>{errors.name.message}</span>}
<input {...register('price', { valueAsNumber: true })} type="number" />
{errors.price && <span>{errors.price.message}</span>}
<button type="submit">저장</button>
</form>
);
}