중첩된 컴포넌트에서 React-hook-form 사용하기

no-pla·2024년 2월 13일
0

트러블 슈팅

목록 보기
3/4
post-thumbnail

문제

컴포넌트를 분리하면서, 중첩된 컴포넌트에서 useForm을 사용해서 유효성 검사를 구현하려 했으나, 작동하지 않았다.
그래서 공식 사이트를 찾아 보다 FormProvider와 useFormContext를 통해 구현하기로 했다.

요약

  • 중첩된 컴포넌트에서 useForm을 사용하려고 했으나, 제대로 작동하지 않음.
  • 그래서 FormProvider로 form을 감싸고, 입력 요소에서 useFormContext로 받아오기로 함

정리

  1. 폼 컴포넌트
    1.1 폼 컴포넌트 함수
    기존과 비슷하지만, FormProvider에 전달해 주어야 하기 때문에 methods로 받아오고, 사용자가 입력할 때마다, 실시간으로 유효성 검사를 진행하기 위해 mode를 추가해 주었다.
  const methods = useForm({
    defaultValues: {
      email: "",
      password: "",
    },
    mode: "onChange",
  });
  1. 폼 컴포넌트
    2.1 form 컴포넌트를 FormProvider로 감싸주고 methodsprops로 전달해 준다.
    2.2 중첩된 요소에 전달할 요소가 있다면, props로 전달해 준다. 내 경우에는, type과 placeholder, validation 등을 전부 전달해 주었다.
        <FormProvider {...methods}>
          <Form onSubmit={methods.handleSubmit((data) => onLogIn(data))}>
            <AuthInput
              validation={{
                pattern: {
                  value: emailRegex,
                  message: "올바른 형식의 이메일이 아닙니다.",
                },
                required: {
                  value: true,
                  message: "필수 입력 값입니다.",
                },
              }}
              placeholder="이메일"
              type="text"
              name="email"
            />
            <AuthInput
              validation={{
                pattern: {
                  value: passwordRegex,
                  message:
                    "비밀번호는 최소 6자 이상, 숫자와 영문자를 모두 포함해야 합니다.",
                },
                required: {
                  value: true,
                  message: "필수 입력 값입니다.",
                },
              }}
              placeholder="비밀번호"
              type="password"
              name="password"
            />
            <Button type="submit">로그인</Button>
          </Form>
        </FormProvider>
  1. 입력 요소 컴포넌트
    3.1 useFormContext를 통해, register과 error 처리를 한다. (이 부분도 기존과 같은 방식(useForm 사용하듯이)으로 하면 될 것 같다.) feat: anyscript
const AuthInput = ({ placeholder, type, name, validation }: any) => {
  const {
    register,
    formState: { errors },
  } = useFormContext<any>();
  const error = errors[name];

  return (
    <>
      <Label htmlFor={name}>{placeholder}</Label>
      {/* placeholder는 스크린 리더가 읽지 못할 수도 있기 때문에 label를 추가해주어야 한다. */}
      <Input
        placeholder={placeholder}
        type={type}
        {...register(name, validation)}
        id={name}
        name={name}
      />
      <ErrorMessage>{error && error?.message?.toString()}</ErrorMessage>
    </>
  );
};
  1. 결과

+) 유효성 검사 방법 바꾸기

useForm에 mode라는 속성을 추가하면 실시간(onChange)이나 제출 시(onSubmit), input에서 벗어났을 때(onBlur) 등의 시점에 유효성 검사를 실시할 수 있다.

  const methods = useForm({
    defaultValues: {
      email: "",
      password: "",
    },
    mode: "onChange",
  });```


참고:

[FromProvider](https://react-hook-form.com/docs/formprovider)

0개의 댓글