react-hook-form, yup

์œค์„ฑํ•ดยท2023๋…„ 4์›” 14์ผ
0

๊ณต๋ถ€ํ•˜๊ธฐ

๋ชฉ๋ก ๋ณด๊ธฐ
11/12

๐Ÿ’ก ์˜ค๋Š˜์€ react-hook-form, yup ์„ ๋ฐฐ์› ๋‹ค! ๊ฐœ๋…์€ ๋ธ”๋กœ๊ทธ์—์„œ ์ ๊ธฐ๋กœ ํ•˜๊ณ , ๊ณผ์ œ ํ•˜๋ฉด์„œ ์ดํ•ดํ•˜๊ณ  ์•Œ๊ฒŒ๋œ ๊ฒƒ๋“ค์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ธฐ๋ก๊ธฐ๋ก

1. react-hook-form ์ ์šฉํ•˜๊ธฐ

์ž‘์„ฑ์ž, ๋น„๋ฐ€๋ฒˆํ˜ธ, ์ œ๋ชฉ, ๋‚ด์šฉ ์ž…๋ ฅ์ฐฝ์„ ๋งŒ๋“ค๊ณ , ๊ฒŒ์‹œ๋ฌผ ๋“ฑ๋กํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋งŒ๋“ค๊ธฐ!

import { useForm } from "react-hook-form";

export default function ReactHookForm() {
  const { register, handleSubmit } = useForm();

  const onClickSubmit = (data) => {
    console.log(data);

  };

  return (
    <form onSubmit={handleSubmit(onClickSubmit)}>
      ์ž‘์„ฑ์ž <input type="text" {...register("writer")} />
      ๋น„๋ฐ€๋ฒˆํ˜ธ <input type="password" {...register("password")} />
      ์ œ๋ชฉ <input type="text" {...register("title")} />
      ๋‚ด์šฉ <input type="text" {...register("contents")} />
      <button>๋“ฑ๋กํ•˜๊ธฐ</button>
    </form>
  );
}

๐Ÿ’ก ์•Œ๊ฒŒ๋œ ๊ฒƒ

โ—๏ธ ์œ„ ์ฝ”๋“œ์—์„œ const { register, handleSubmit } = useForm(); ์•ˆ์˜ register, handleSubmit์ด ๋ญ˜๊นŒ... ๋ชจ๋ฅด๊ฒ ์–ด์„œ ์•Œ์•„๋ณธ ๊ฒฐ๊ณผ, register๋Š” input์ฐฝ "writer"์— ์ ํžŒ ๊ฐ’๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค. ์œ„์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ  ์ธํ’‹์ฐฝ์— '์•ˆ๋…•!' ์ด๋ผ๊ณ  ์ ์œผ๋ฉด ์ฝ˜์†”์—์„œ ๊ฐ์ฒด์•ˆ์— writer:"์•ˆ๋…•!" ์„ ๋ณผ ์ˆ˜๊ฐ€ ์žˆ์—ˆ๋‹ค. โžก๏ธ writer ๋ฅผ title๋กœ ๋ฐ”๊พธ๋ฉด title์•ˆ์— ๊ฐ’์ด ๋ถˆ๋Ÿฌ์™€์ง„๋‹ค. ์ผ๋‹จ์€ key ๋„ค์ž„ ์ƒ์„ฑ์ด๋ผ๊ณ  ์ดํ•ดํ–ˆ๋‹ค.

โ—๏ธ <form onSubmit={handleSubmit(onClickSubmit)}> ์— ์ ํžŒ onSubmit์€ Submit๋งŒ ํ•ด์ฃผ๋Š”๊ฒŒ ์•„๋‹ˆ๋‹ค. ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๋Š” onClickํ•จ์ˆ˜์˜€๋Š”๋ฐ, react-hook-form ์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ์จ์ฃผ๋‚˜๋ณด๋‹ค.

โ—๏ธ handleSubmit ์„ ๋ฐ”์ธ๋”ฉํ•ด์•ผ ์ง„์งœ๋กœ ์‹คํ–‰์‹œ์ผœ์ค„ ํ•จ์ˆ˜๋“ค์ด ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค.
โ—๏ธ handleSubmit์€ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›์œผ๋ฉฐ ๊ทธ ํ•จ์ˆ˜์— data๋ผ๋Š” ์ธ์ž๋ฅผ ๋„˜๊ฒจ์ฃผ์ง€๋งŒ (data)์•ˆ์— data๋Š” ddd๋ผ๊ณ  ๋ฐ”๊ฟ”๋„ ์‹คํ–‰์ด ๋˜๋”๋ผ!

โ—๏ธ input์— ์ฐํžˆ๋Š” ๊ฐ’์€ watch ๋ผ๋Š” ์˜ต์…˜์„ ์ด์šฉํ•ด์„œ ๊บผ๋‚ด๋ณผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

2. yup ์‚ฌ์šฉํ•ด์„œ ์—๋Ÿฌ๋ฉ”์„ธ์ง€ ๋„์šฐ๊ธฐ

์œ„์— ๋งŒ๋“  ํผ์— ์กฐ๊ฑด์„ ์„ค์ •ํ•˜๊ณ , ๋งž์ง€ ์•Š์œผ๋ฉด yup์„ ์ด์šฉํ•˜์—ฌ ์—๋Ÿฌ๋ฉ”์„ธ์ง€๋ฅผ ๋„์› ๋‹ค.

1-1) ์ž‘์„ฑ์ž๋Š” 5๊ธ€์ž ์ด๋‚ด ๋ฌธ์ž์—ด
1-2) ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์˜๋ฌธ, ์ˆซ์ž, ํŠน์ˆ˜๋ฌธ์ž๋ฅผ ํฌํ•จํ•œ 8์ž๋ฆฌ ์ด๋‚ด ๋ฌธ์ž์—ด
1-3) ์ œ๋ชฉ์€ 100์ž ์ด๋‚ด ๋ฌธ์ž์—ด, ๋‚ด์šฉ์€ 1000์ž ์ด๋‚ด ๋ฌธ์ž์—ด

๐Ÿ’ก ์•Œ๊ฒŒ๋œ ๊ฒƒ

์œ„ ์ฝ”๋“œ๊ฐ€ ๋‚ด๊ฐ€ ํ•œ์‹œ๊ฐ„ ๋ฐ˜๋™์•ˆ ์žก๊ณ ์žˆ๋˜ ์—๋Ÿฌ..! ๋…ธ๋“œ๋ชจ๋“ˆ์ฆˆ๊ฐ€ ์ด์ƒํ•œ๊ฐ€? ๋ถ„๋ช… ์†์„ฑ์ด ์žˆ๋Š”๋ฐ ์™œ ์ €๋Ÿฌ๋Š”๊ฑฐ์ง€ ์‹ถ์–ด์„œ ๋…ธ๋“œ๋ชจ๋“ˆ์ฆˆ ์ง€์› ๋‹ค ๊น”์•„๋ณด๊ณ  ํ–ˆ๋Š”๋ฐ ์ ˆ๋Œ€ ๊ทธ์ง(?)๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ์—ˆ์Œ.ใ…Ž.ใ…Žใ…Žใ…Ž..ใ…Žใ…Žใ…Žใ…Ž (๋„์™€์ฃผ์‹  ์ฒœ์žฌ๋‹˜๊ป˜ ๊ฐ์‚ฌ..)

    password: yup
      .string()
      .matches(
        /(?=.*\d)(?=.*[~`!@#$%\^&*()-+=])(?=.*[a-zA-Z]).{1,8}$/,
        "๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์˜๋ฌธ, ์ˆซ์ž, ํŠน์ˆ˜๋ฌธ์ž๋ฅผ ํฌํ•จํ•œ 8์ž๋ฆฌ ์ด๋‚ด๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"
      ),

์ด๋ ‡๊ฒŒ ํƒ€์ž…์ง€์ •์„ ํ•ด์ฃผ๋‹ˆ๊นŒ ์—๋Ÿฌ๊ฐ€ ์‚ฌ๋ผ์กŒ๋‹ค. โžก๏ธ .string()์ถ”๊ฐ€ํ–ˆ์Œ!!!

3. custom-hooks ๋งŒ๋“ค๊ธฐ!

๊ธฐ์กด์— useState๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์นด์šดํŠธ ๋ฒ„ํŠผ์„ ๋งŒ๋“ค์—ˆ๋˜ ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๋Š” ๊ณผ์ œ์˜€๋‹ค.
๊ธฐ์กด ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค!

import { useState } from "react";

export default function QuizPage() {
  const [count, setCount] = useState(0);

  const onClickCountUp = () => {
    setCount((prev) => prev + 1);
  };

  return (
    <>
      <div>
        <p>์ง€๊ธˆ์˜ ์นด์šดํŠธ๋Š” {count} ์ž…๋‹ˆ๋‹ค!</p>
        <button onClick={onClickCountUp}>Count up!</button>
      </div>
    </>
  );
}

๋ฆฌํŒฉํ† ๋ง ํ›„ ์ฝ”๋“œ

import { useForm } from "react-hook-form";

export default function QuizPage() {
  const { handleSubmit, formState } = useForm();

  const CountUp = () => {};

  return (
    <>
      <form onClick={handleSubmit(CountUp)}>
        <div>{formState.submitCount} </div>
        <button>Count up!</button>
      </form>
    </>
  );
}

๐Ÿ’ก ์•Œ๊ฒŒ๋œ ๊ฒƒ

์›๋ž˜๋Š” state์— ๋‹ด์•„์„œ ์ฒ˜๋ฆฌํ•ด์ฃผ๋˜๊ฒƒ์„ ์ด๊ฑด ๋„๋Œ€์ฒด ์–ด๋””์— ๋ญ˜ ๋‹ด์œผ๋ผ๋Š”๊ฑฐ์ง€ ํ•˜๊ณ ์žˆ์—ˆ๋Š”๋ฐ
์•Œ์•„๋ณด๋‹ˆ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๋Š” ์˜ต์…˜๋“ค์ด ์—„์ฒญ ๋งŽ์•„์„œ, ์ž˜ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌ์—ˆ๋‹ค!
๋‚ด๊ฐ€ ์‚ฌ์šฉํ•œ๊ฑด forState์•ˆ์— ์žˆ๋Š” submitCount !!!

์‚ฌ์šฉํ•˜๋‹ˆ,, ๊ทธ๋ƒฅ ์ง„์งœ {formState.submitCount} ์ด๋ ‡๊ฒŒ๋งŒ ์ ์–ด์ฃผ๋ฉด ๋˜์–ด์„œ ์•„์ฅฌ ํŽธ๋ฆฌํ–ˆ๋‹ค.
์–ด๋–ค ์˜ต์…˜๋“ค์ด ์žˆ๋Š”์ง€ ์ž˜ ์•Œ๊ณ ์žˆ์–ด์•ผ ํ• ๋“ฏ!! ์–ด๋ ต๋‹ค์–ด๋ ค์›Œ

์ฐธ๊ณ ํ•œ ๊ธ€

profile
Slow and steady wins the race.

0๊ฐœ์˜ ๋Œ“๊ธ€