[React] react-hook-form 사용하기

Arin·2021년 4월 18일
5

React

목록 보기
1/2

react-hook-form은 form형식의 컴포넌트들을 좀 더 편하게 구현할 수 있도록 만든 라이브러리이다.

글을 작성한 이유는 다양한 input타입을 react-hook-form으로 만드는 방법을 기록해 놓기 위해서 이다. 게다가 react-bootstrap의 스타일 라이브러리를 사용했기 때문에 홈페이지에 나온 코드 예시에는 찾을 수가 없어서 기록이 꼭 필요했다.

우선 react-hook-form을 사용하면 useState를 사용한 변수를 만들지 않아도 되긴 하는데, 이는 나중에 api 연동에 따라 변수를 만들어야 될 수도 있다.

기본적인 형태는 다음과 같다.

function app (){
    const { register, handleSubmit, control } = useForm();
  
  const onValue= (data) => {
     console.log(data)
  }
  
  return(
    <form onSubmit={handleSubmit(onValue)}>
       ........
       .....
       ....
       ..
      
      <button type="submit">제출</button>
    </form>
  )

}

form태그로 감싸고, handleSubmit( ) 함수에 데이터를 다 담는다. 그리고 데이터를 어떻게 처리할 지에 대한 함수를 ( )안에 넣으면 된다.

다른 UI라이브러리의 컴포넌트를 같이 사용하기 위해서는 를 사용해야 한다. render 속성에다가 UI컴포넌트를 넣는데, 이때 매개변수부분을 잘 이해하는 것이 중요하다.

1.input text 타입

<Form.Group>
  <Controller
    	control={control}
    	name="brand"
    	render={({ field }) => {
  		return <FormControl {...field} />;
		}}
	/>
</Form.Group>

2. checkbox 타입

checkbox는 input하나당 boolean형태의 값을 만들어 낸다.
그래서 중복 체크가 가능하다.

<Form.Group>
    {coffee.map((item) => {
      return (
        <div className="checkbox-set" key={item.idx}>
          <Controller
          name={item.title}
          control={control}
          render={({
             field: { onChange, onBlur, value, name, ref },
             fieldState: { invalid, isTouched, isDirty, error },
             formState,
             }) => {
            return <FormCheck checked={value} onChange={onChange} />;
          }}
          />
        <Form.Label>{item.title}</Form.Label>
       </div>
      );
  })}
</Form.Group>

render 속성 안의 함수의 매개변수를 보면 다음과 같다.

field: { onChange, onBlur, value, name, ref },
fieldState: { invalid, isTouched, isDirty, error },
formState

주로 field 부분이 자주 사용된다.

3. radio타입

radio는 여러개의 input을 가지고 하나의 결과를 만들어 낸다.
그렇기 때문에 의 render 함수 안에서 radio 컴포넌트를 여러개 생성한다.

<Controller
  name="gift_card"
  control={control}
  render={({ field }) => {
    return (
      <Form.Group {...field}>
        {giftCard.map((item) => {
          //console.log('field.value', field.value);
          return (
            <FormCheck
              key={item.idx}
              type="radio"
              label={item.title}
              id={item.idx.toString()}
              name={field.name}
              value={item.title} 
              //true 된 값의 value가 최종 value가 된다.
              checked={field.value == item.title}
              // 클릭한 e.target.value 값과 field.value가 같으면 true 반환
              onChange={(e) => {
                //console.log('e.target', e.target.value);
                field.onChange(e.target.value);
              }}
              />
          );
        })}
      </Form.Group>
    );
  }}
  />
  • radio는 같은 name을 가진 radio들을 셋트로 묶는다.
  • radio의 checked가 true가 된 대상의 value가 최종 값이다.
  • checked가 true로 되는 것은 하나 뿐이다.
  • "name" : "value"(checked가 true인 대상의 value)

4.switch 타입

switch는 label과 value 두가지 결과를 내보낸다.
value은 boolean타입이고, checked 속성에 의해 결정된다.
그래서 onChange함수의 매개변수가 e.target.checked 인 점이 특징이다.

<Form.Group>
  <Controller
    name="message"
    control={control}
    render={({ field }) => {
      return (
        <FormCheck
          type="switch"
          id="custom-switch"
          label={field.value ? 'use' : 'unuse'}
          checked={field.value}
          onChange={(e) => {
            field.onChange(e.target.checked);
          }}
          />
      );
    }}
    />
</Form.Group>

switch가 여러개일 경우 array를 이용해서 코드를 짜고 싶은데, 이게 만만치 않다.
각각 switch가 작동하도록 해야 하는데 쉽지 않다...

profile
2년차 프론트앤드

0개의 댓글