React Hook Form과 Zod를 활용한 로그인, 회원가입 폼 구현

henry·2024년 1월 23일
2
post-thumbnail

⚠️ 본 포스트는 프로젝트 기록용으로, 개념에 대한 설명이나 라이브러리의 특성에 대해 설명하지 않습니다.

로그인 페이지

React에서 상태값을 관리할 때 useState를 주로 사용한다. 아래의 코드는 useState를 사용하여 password 값을 관리하는 예시 코드다.

  const [password, setPassword] = useState<string>("");

  const onChangePassword = (e: React.ChangeEvent<HTMLInputElement>) => {
    setPassword(e.target.value);
  };

  return (
    <input
      placeholder="******"
      type="password"
      onChange={onChangePassword}
    />
  )

React의 제어 컴포넌트 특성으로, state가 업데이트될 때마다 컴포넌트가 리렌더링이 발생하게 된다. 이로 인해 컴포넌트의 state가 변경되면 props로 전달받은 자식 컴포넌트도 함께 리렌더링이 발생하며, 불필요한 렌더링이 발생할 수 있어 성능에 영향을 줄 수 있다.

React Hook Form을 사용한 로그인 페이지 구현

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

  const form = useForm({
    defaultValues: {
      email: "",
      password: "",
    },
  });

  return (
     <Form {...form}>
       <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
         <FormField
            control={form.control}
            name="password"
            render={({ field }) => (
              <FormItem>
                <FormLabel htmlFor="password">Password</FormLabel>
                <FormControl>
                  <Input {...field} placeholder="******" type="password" />
                </FormControl>
              </FormItem>
            )}
          />
		</form>
  )

전체 부분이 리렌더링이 발생하지 않고 변경된 필드만 다시 렌더링 하여 최적화된 것을 확인할 수 있다

회원가입 페이지

회원가입 페이지는 이름, 이메일, 비밀번호 3가지 정보를 입력받고 Create an account 버튼을 눌러서 유효성 체크 후 올바르지 않게 입력한 경우 에러 메시지를 표시한다

Zod로 유효성 검증

Zod는 형식에 맞는 스키마 인스턴스를 생성하고, infer를 통해 자동 타입 추론이 가능하다.

Zod 스키마를 사용하여 회원가입 페이지 구현

// schema 정의
import * as z from "zod";

export const RegisterSchema = z.object({
  name: z.string().min(1, {
    message: "Name is required",
  }),
  email: z.string().email(),
  password: z.string().min(1, {
    message: "Minimun 6 characters required",
  }),
});

// Zod의 infer과 JS의 `typeof` 연산자를 사용해서 이미 정의한 스키마로 부터 타입을 추출
// 정의한 스키마를 zodResolver의 인수로 넣어준다
  const form = useForm<z.infer<typeof RegisterSchema>>({
    resolver: zodResolver(RegisterSchema),
    defaultValues: {
      email: "",
      password: "",
      name: "",
    },
  });

  return(
   <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">  
   		<FormField
          control={form.control}
          name="name"
          render={({ field }) => (
            <FormItem>
            <FormLabel htmlFor="name">Name</FormLabel>
            <FormControl>
            <Input
            {...field}
          disabled={isPending}
          placeholder="Henry"
        />
          </FormControl>
        <FormMessage />
          </FormItem>
        )}
        />
...
  )

불필요한 리렌더링도 발생하지 않고 유효성 체크까지 손쉽게 구현

만약 react-hook-formzod 라이브러리를 사용하지 않고 폼 상태 관리 및 유효성 체크 코드를 작성했다면 렌더링 최적화도 안 되고, 코드가 길어지고 복잡해졌을 것이다

  const [formValues, setFormValues] = useState({
    email: "",
    password: "",
    name: "",
  });

  // 유저가 입력한 값이 유효한지 검사
  const [formErrors, setFormErrors] = useState({
    email: false,
    password: false,
    name: false,
  });

  const validateForm = () => {
    if (password.length < 6)
      setFormErrors({
        ...formErrors,
        password: "비밀번호는 6자 이상이어야 합니다.",
      });
    if ()...
  };
  ...

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    switch (e.target.name) {
      case "email":
        setFormValues({
          ...formValues,
          email: e.target.value,
        });
        break;
      case "password":
        setFormValues({
          ...formValues,
          password: e.target.value,
        });
        break;
      case "name":
        setFormValues({
          ...formValues,
          name: e.target.value,
        });
        break;
    }
  };

참고 자료

1개의 댓글

comment-user-thumbnail
2024년 11월 28일

저는 프로젝트시 React Hook Form으로 유효성 검사도 진행한 경험이 있는데 zod라는 방식도 있군요! 배워갑니다 👍🏻

답글 달기

관련 채용 정보