[react-hook-form 오류] 커스텀 Input 컴포넌트 사용 시 값이 undefined로 인식되는 문제 (feat. forwardRef)

허지예·2024년 8월 13일
0

개인 프로젝트 기록

목록 보기
13/17

react-form-hook

React에서 폼을 쉽게 관리하고 유효성 검사를 효율적으로 처리할 수 있도록 도와주는 라이브러리

  • 폼 상태를 최소화하고, 불필요한 리렌더링을 방지하여 성능을 최적화
  • 사용하기 쉬운 API, useForm 훅을 사용하여 폼을 초기화하고, register를 통해 각 폼 필드를 간단하게 관리할 수 있다.
  • 커스텀 유효성 검사도 쉽게 추가할 수 있다.

나는 이번에 이 react-form-hook을 사용해서 폼을 구현했는데, input 컴포넌트를 적절히 스타일링한 <Input/> 컴포넌트를 활용해서 폼을 구현했다.

그런데, 부모 form 컴포넌트 > Input 컴포넌트 > input DOM에 접근하는 과정 중에 문제가 발생했다.

문제 상황

간단히 새로 작성한 예시 코드여요

MyForm 컴포넌트

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

function MyForm() {
  const { register, handleSubmit } = useForm();

  const onSubmit = (data: any) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <MyInput {...register('username')} placeholder="Username" />
      <button type="submit">Submit</button>
    </form>
  );
}

MyInput 컴포넌트

type MyInputProps = React.InputHTMLAttributes<HTMLInputElement>;

function MyInput(props: MyInputProps) {
  return <input ref={ref} {...props} />;
};

문제 설명

register()의 반환 값은 다음과 같다.

{
  name: string                                                    // 필드의 name 속성
  ref: (instance: HTMLInputElement | null) => void,               // ref 콜백 함수
  onChange: (event: React.ChangeEvent<HTMLInputElement>) => void,  // 값이 변경될 때 호출되는 함수
  onBlur: (event: React.FocusEvent<HTMLInputElement>) => void,    // 필드가 포커스를 잃을 때 호출되는 함수
}

그런데 MyInput으로 props로 넘어오는 값들을 살펴보면 name, onChange, onBlur 뿐이다.

그래서 onChange는 인식되서 값이 바뀐 걸 읽어보려 하지만 ref가 연결되지 않았기 때문에 input 값으로 undefined가 인식되버린다.

그래서 forwardRef가 필요하다.

  • React에서 컴포넌트가 자신의 자식 컴포넌트나 DOM 요소에 대한 참조(Ref)를 부모 컴포넌트에서 직접 전달할 수 있도록 하는 고차 함수
  • 주로 복잡한 컴포넌트 구조에서 부모 컴포넌트가 특정 자식 컴포넌트의 DOM 요소나 인스턴스에 접근해야 할 때 사용한다.

forwardRef로 MyInput 컴포넌트를 생성하도록 수정

import { forwardRef } from 'react';

type MyInputProps = React.InputHTMLAttributes<HTMLInputElement>;

const MyInput = forwardRef<HTMLInputElement, MyInputProps>((props, ref) => {
  return <input ref={ref} {...props} />;
});

이러면 해결된다 👍

끝!

profile
대학생에서 취준생으로 진화했다가 지금은 풀스택 개발자로 2차 진화함

0개의 댓글

관련 채용 정보