image.png

์•ˆ๋…•ํ•˜์„ธ์š”!

Zod์™€ React Hook Form์—์„œ ์ œ๊ณตํ•˜๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ›…๋“ค์„ ์‚ฌ์šฉํ•ด ํผ์„ ๋ง›์žˆ๊ฒŒ ๋‹ค๋ฃจ์–ด๋ณด๋Š” ๋ฐฉ๋ฒ•์—๋Œ€ํ•ด ์ž‘์„ฑํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค !

1๏ธโƒฃย ๋ฆฌํ›…ํผ๊ณผ Zod๋ฅผ ํ†ตํ•œ ์œ ํšจ์„ฑ ๊ฒ€์ฆ


๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฆฌํ›…ํผ์€ HTML์†์„ฑ ๊ธฐ๋ฐ˜ ๊ฒ€์ฆ์„ ์ง€์›ํ•˜์ง€๋งŒ, ๋” ๋ณต์žกํ•œ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์ด๋‚˜ ์ปค์Šคํ…€ ๋กœ์ง์„ ์ ์šฉํ•˜๋ ค๋ฉด ์™ธ๋ถ€ ๊ฒ€์ฆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์ผ๋ฐ˜์ ์œผ๋กœ zod, yup, joi ๊ฐ™์€ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด! ๋”์šฑ ํฐ ์‹œ๋„ˆ์ง€๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ ์ค‘์—์„œ๋„ Zod๋Š” TypeScript์™€ ๊ฐ•๋ ฅํ•œ ํ†ตํ•ฉ์„ ๋ชฉํ‘œ๋กœํ•˜๋Š” ์„ ์–ธ์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฉฐ ์ตœ๊ทผ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ์ด๊ณ ์žˆ๋‹ค.

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2024-11-26 แ„‹แ…ฉแ„’แ…ฎ 2.39.57.png

<aside> ๐Ÿ’ก

Zod๋ž€ ?

JS, TS์—์„œ ์Šคํ‚ค๋งˆ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ๋ฐ ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑ์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๊ณ , ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉฐ React Hook Form๊ณผ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

</aside>

๋ฆฌํ›…ํผ์—์„œ Zod๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฆฌํ›…ํผ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ณ„๋„์˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํŒจํ‚ค์ง€์ธ hookform/resolvers๋ฅผ ์„ค์น˜ํ•ด์ค˜์•ผํ•œ๋‹ค.

hookfrom/resolvers๋Š” ๋‹ค์–‘ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋ฆฌํ›…ํผ์˜ ํ†ตํ•ฉ์„ ์ง€์›ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.

โš™๏ธย ์ ์šฉํ•ด๋ณด๊ธฐ

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

const userSchema = z.object({
  username: z.string().min(3, "์ด๋ฆ„์€ ์ตœ์†Œ 3์ž ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."),
  password: z.string().min(6, "๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์ตœ์†Œ 6์ž ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."),
}); // Zod ์Šคํ‚ค๋งˆ ์ •์˜

const { register, handleSubmit, formState: { errors } } = useForm({
  resolver: zodResolver(schema),
}); // ํผ์— ์Šคํ‚ค๋งˆ ์ ์šฉ

๊ธฐ๋ณธ ๋ฌธ์ž์—ด ๊ฒ€์ฆ, ๊ธธ์ด ๊ฒ€์ฆ ์™ธ์—๋„ ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๋ฉ”์„œ๋“œ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.