티스토리 뷰

반응형

1. 하나의 Form에 여러개의 공통된 Input을 쓴다면?

컴포넌트 팡인 우리 조🧚🏻 답게 이미 귀여운 inpiut 디자인까지 다 뽑아두었건만!!!

react-hook-form을 쓰면 내가 만들어둔 귀여운 디자인의 Input을 못쓰는 거 아닌가!? 인라인 스타일로 css 다 다시 박아넣으라구?!!? 당장 재.활.용 내놔. 라고 생각할 때 아주 소중한 글을 발견했다.

바로 useController라는 훅을 사용하면 내 입맛대로 custom이 가능하다는 것!!

자세한 것은 공식문서를 참고하면서 진행하겠습니다.

useController
React hooks for controlled component useController:(props?: UseControllerProps) => { field: object, fieldState: object, formState: object } This custom hook powers Controller . Additionally, it shares the same props and methods as Controller. It's useful for creating reusable Controlled input. The following table contains information about the arguments for useController.
https://react-hook-form.com/api/usecontroller

2. Use Controller 맛보기

2-1. 파라미터

먼저 useController 가 사용하는 props(즉 파라미터로 받는 객체들) 는 Controller 와 같다.

NameTypeOption
nameFieldPath
controlControlreact-hook-form의 일부로 제어할 수 있도록 넣어주는 개체
rulesObject

그 외에도 defaultValueshouldUnregister가 있다. 자세한 사항은 공식문서를 참고하면 좋을 것 같다.

특히 defaultValue 사용 시에 값을 제공한다면 반드시 useForm에 defaultValue를 넣어서 undefined를 만들지 않도록 해야한다.

2-2. 리턴해주는 객체

리턴해주는 속성에는 크게 3가지가 있다.

field fieldState formState

먼저 field에는 input에 직접적으로 들어가는 value, name, onChange 가 담겨있다.

fieldState 는 invalid, isTouched, error 등 해당 필드의 상태를 관리한다. 또 onBlur나 ref 속성도 사용할 수 있어서 컴포넌트 작업할 때 편리하게 필드를 관리할 수 있다. (onBlur는 Input창을 선택하지 않았을 때, 즉 focus의 반대상황일 때 실행되는 이벤트)

3. 이제 진짜 사용해보자 컨트롤러

재활용하고 싶은 Input 컴포넌트를 만들어보자.

중간에 rules에 있는 Omit< A, B> 부분은 A 라는 타입에서 B 속성을 제외한 interface를 사용한다고 이해하면 된다. 제네릭타입에 대한 자세한 설명은 여기를 클릭하자

  • 코드 예시보기 ( 재활용할 컴포넌트 이름 : InputForm.tsx)
    src/components/Input/InputForm.tsx
    
    import {
      Control,
      FieldPath,
      FieldValues,
      RegisterOptions,
      useController,
      useForm,
    } from 'react-hook-form';
    
    export type TControl<T extends FieldValues> = {
      control: Control<T>;
      name: FieldPath<T>;
      rules?: Omit<
        RegisterOptions<T>,
        'valueAsNumber' | 'valueAsDate' | 'setValueAs' | 'disabled'
      >;
    };
    
    function InputForm({ control, name, rules }: TControl<any>) {
      const {
        field: { value, onChange },
      } = useController({ name, rules, control });
      return <input className="input" value={value} onChange={onChange} />;
    }
    
    export default InputForm;

이제 내가 필요한 곳에 가져와서 사용하면 된다!

  • 코드 예시보기
    src/pages/LoginPage
    
    import InputForm from '@/components/Inputs/Input/InputForm';
    import { useForm, SubmitHandler } from 'react-hook-form';
    
    
    // typescript이기 때문에 interface를 지정해줘야 한다.
    interface IFormInput {
      firstName: String;
    }
    
    function LoginPage() {
      const {
        control,
        handleSubmit,
        formState: { errors },
      } = useForm<IFormInput>();
      const onSubmit: SubmitHandler<IFormInput> = (data) => console.log(data);
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <InputForm
            name="firstName"
            control={control}
            rules={{ required: true }}
          />
          <p>{errors.firstName && 'First name is required'}</p>
          <input type="submit" />
        </form>
      );
    export default LoginPage;

결과는?

두구두구두구……

먼저 required:true 를 적용했기 때문에, 빈칸을 submit하면 input 창 아래에 에러메세지가 나온다.

반대로 input 창에 Harim이라고 제출하면 console 창에 보면 아름답게 잘 실행됨을 확인할 수 있다.

4. Tailwind를 사용해서 더 아름답게 디자인하기


참고한 글

react-hook-form 과 MUI 함께 사용하기 - 오픈소스컨설팅 테크블로그
안녕하세요. Playce Dev 팀에서 Frontend 개발을 하고 있는 강동희 입니다. 이번 포스팅은 react-hook-form 시리즈의 두 번째 포스팅으로 프론트엔드 파트의 react 프로젝트에 react-hook-form 을 도입하며, 공부 했고 고민했던 과정들을 여러분들께 공유하는 시간을 갖도록 하겠습니다. 저번 포스팅에서는 먼저 제어 컴포넌트로 간단한 form 을 만들어봤고, 이 form 에 react-hook-form 을 적용해보며 핵심 hook 인 useForm 에 대해서 살펴봤습니다.
https://tech.osci.kr/2023/01/05/react-hook-form-with-mui/


Uploaded by N2T

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함