lil.dev
Published on

๐ŸŽ‰ ์ปฌ๋Ÿฌ๋ฆฌ์ŠคํŠธ ํ”„๋กœ์ ํŠธ #3 ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๊ธ€์“ด์ด

    ๐Ÿ“Œ ๋ชฉ์ฐจ

    Welcome

    โœจ ์ปฌ๋Ÿฌ๋ฆฌ์ŠคํŠธ ์‚ฌ์ดํŠธ(์•„์ง ์—†์Œ

    ๐Ÿ’๐Ÿป

    1. ์‹œ๋‚˜๋ฆฌ์˜ค ์“ฐ๊ธฐ
    2. ์ฝ”๋“œ ์งœ๊ธฐ ์‹œ์ž‘
    • 2.1 ๋กœ๊ทธ์ธ ํผ ๋งŒ๋“ค๊ธฐ ๐Ÿฅš
    • 2.2 ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น ๋ฐ ์—๋Ÿฌ๋ฉ”์‹œ์ง€ ๊ตฌํ˜„ ๐Ÿฅš

    1. ์‹œ๋‚˜๋ฆฌ์˜ค ์“ฐ๊ธฐ

    Feature: Login
    
    Scenario: login form์„ ๋งŒ๋“ ๋‹ค
      Given login form ๋ Œ๋”ํ•˜๊ณ 
      When ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๊ณ 
      When "๋กœ๊ทธ์ธ" button์„ ํด๋ฆญํ•˜๋ฉด
      Then ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค ๋ฌธ๊ตฌ๊ฐ€ ๋œฌ๋‹ค!
      Then nav์˜ login์ด ํ”„๋กœํ•„ ์‚ฌ์ง„๊ณผ ์ด๋ฆ„์œผ๋กœ ๋ฐ”๋€๋‹ค
    

    ์•„์ง์€ ๋ฌธ๊ตฌ๊ฐ€ ๋œจ๋Š” ๊ฒƒ๊นŒ์ง€๋งŒ ๊ตฌํ˜„ํ–ˆ๋‹ค.

    2. ์ฝ”๋“œ ์งœ๊ธฐ ์‹œ์ž‘

    Login.tsx ์ž‘์„ฑ์„ ์‹œ์ž‘ํ–ˆ๋‹ค.

    1. bun add react-hook-form ์„ ํ„ฐ๋ฏธ๋„์— ์ž…๋ ฅํ•ด์„œ ์„ค์น˜ํ–ˆ๋‹ค.

    2. 'Login.tsx'์— useForm์„ import ํ•ด์ฃผ์—ˆ๋‹ค. -> import { useForm } from "react-hook-form"; https://react-hook-form.com/get-started ์ฐธ์กฐ

    3. ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ธฐ๋ณธ ๋กœ๊ทธ์ธ ํผ์„ ๋งŒ๋“ค์–ด์ค€๋‹ค.

      <article className="login-form">
        <form>
          <h2>Login</h2>
          <label>
            ์ด๋ฉ”์ผ
            <input type="email" />
          </label>
      
          <label>
            ๋น„๋ฐ€๋ฒˆํ˜ธ
            <input type="password" />
          </label>
          <button type="submit">๋กœ๊ทธ์ธ</button>
        </form>
      </article>
      
    4. input์— ์ž…๋ ฅํ•œ ๊ฐ’์„ ๊ธฐ์กด ๊ฐ’๊ณผ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ’์„ ๋ณด๋‚ด์ฃผ์–ด์•ผ ํ•˜๋‹ˆ๊นŒ,
      register๊ณผ handleSubmit๋ฅผ ๋งŒ๋“ค์–ด์„œ, ๊ฐ์ฒด๋ฅผ ๊ตฌ์กฐ๋ถ„ํ•ด ํ• ๋‹น(destructuring)...ํ•ด์ค€๋‹ค.

      ์ฐธ๊ณ ๋กœ options, config, props..๋Š” ๋‹ค ๋น„์Šทํ•œ ๋ง!

    function Login() {
      const {
        register,
        handleSubmit,
        formState: { errors },
      } = useForm({
        defaultValues: {
          email: '',
          password: '',
          //๊ธฐ๋ณธ ๊ฐ’์€ ๋‹ค ""๋กœ ์ •ํ•ด๋†“๋Š”๋‹ค.
        },
      })
    
      return (
        <article className="login-form">
          {/* handleSubmit์€ ํผ์ด ์ œ์ถœ ๋˜์—ˆ์„ ๋•Œ form์˜ data๋ฅผ ์™ ๊บผ๋‚ด์ค€๋‹ค */}
          {/* ์ด๊ฑธ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด์ฃผ๋ฉด ๋! */}
          <form
            onSubmit={handleSubmit((data) => {
              alert(JSON.stringify(data))
              //์ง€๊ธˆ์€ ๋ณด๋‚ด์ค€ ๊ฐ’์„ alert์ฐฝ์—์„œ ๋ณด๊ฒŒํ•ด์ฃผ๋Š” ์ •๋„๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.
            })}
          >
            <h2>Login</h2>
            <label>
              ์ด๋ฉ”์ผ
              <input
                type="email"
                {...register('email', {
                  required: '์ด๋ฉ”์ผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”!',
                })}
              />
            </label>
            {errors.email && <li role="alert">{errors.email.message}</li>}
            //์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉด ์ž‘์„ฑํ•œ ์ธํ’‹๋‚ด์šฉ๊ณผ ์ด๋ฉ”์ผ์˜ ์—๋Ÿฌ๋ฉ”์‹œ์ง€๋ฅผ input์นธ ๋ฐ‘์—์„œ ๋ณด์—ฌ์ค€๋‹ค.
            <label>
              ๋น„๋ฐ€๋ฒˆํ˜ธ
              <input
                type="password"
                {...register('password', {
                  required: '๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”!',
                })}
              />
            </label>
            {errors.password && <li role="alert">{errors.password.message}</li>}
            //์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉด ์ž‘์„ฑํ•œ ์ธํ’‹๋‚ด์šฉ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ์˜ ์—๋Ÿฌ๋ฉ”์‹œ์ง€๋ฅผ input์นธ ๋ฐ‘์—์„œ ๋ณด์—ฌ์ค€๋‹ค.
            <button type="submit">๋กœ๊ทธ์ธ</button>
          </form>
        </article>
      )
    }
    
    export default Login
    
    inputErrorimg