React-hook-form - useController

hwisaac·2023년 2월 18일
1

https://react-hook-form.com/api/usecontroller

useController: (props?: UseControllerProps) => { field: object, fieldState: object, formState: object }

  • This custom hook powers Controller
  • 또한 Controller 컴포넌트와 동일한 propsmoethods를 공유합니다.
  • 재사용 가능한 controlled input을 만드는 데 유용합니다.

Props

NameTypeRequiredDescription
nameFieldPathrequiredinput 의 유일한 이름
controlControluseForm을 호출하여 제공되는 Control 객체.
FormProvider를 사용하는 경우 Optional
defaultValueunknown주의!undefined값을 defaultValue로 설정하지마세요
field-level에서 defaultValue를 설정하거나 useForm의 defaultValues를 설정해야 합니다.
당신의 form이 resetdefault values와 함께 reset을 호출하려면, useFormdefaultValues를 제공해야 합니다
ruleObejctregister와 동일 포맷의 Validation rules 입니다. (다음을 포함합니다: required, min, max, minLength, maxLength, pattern, valdiate)
shouldUnregisterboolean=falseInput이 unmount 이후 unregistered 됩니다. 그리고 defaultValues도 제거됩니다.
useFieldArray를 사용할 경우에는,이 prop을 쓰지말아야 합니다.

Return

Object NameNameTypeDescription
fieldonChange(value: any) => voidinput값들을 library로 보내는 함수
- 입력의 onChange prop에 할당되어야하며 값은 정의되지 않아야 합니다.
- 이 prop은 formState를 업데이트합니다. (매뉴얼적으로 setValue를 쓰거나 field를 업데이트를 하는 API 를 쓰지마세요.)
fieldonBlur()=>voidinput의 onBlur이벤트를 라이브러리에 보내는 함수. 인풋의 onBlur프롭에 할당해야합니다.
fieldvalueunknowncontrolled component의 현재 value
fieldnamestring등록되는 input의 name
fieldrefReact.refhook form과 input을 연결하는데 쓰는 ref. input컴포넌트의 ref에 할당해야 에러 인풋에 초점을 맞춥니다
fieldStateinvalidboolean현재 인풋의 유효하지 않은 state
fieldStateisTouchedboolean현재 컨트롤되는 input 의 touched state
fieldStateisDirtyboolean현재 컨트롤되는 input의 dirty state
fieldStateerrorobject특정 input에 대한 에러
formStateisDirtybooleandefaultValue와 비교해서 유저가 input을 수정하면 true가 됩니다.
formStatedirtyFieldsobject유저가 수정한 필드를 모은 object.
formStatetouchedFieldsobject유저가 상호작용했던 inputs들을 모아놓음
formStatedefaultValuesobjectuseFormdefaultValues로 설정한 값(또는 reset API를 통해 defaultValues를 업데이트한 값)들을 모아놓음
formStateisSubmittedbooleanform이 제출되면 true. reset 메서드가 호출될때까지 true가 유지됩니다.
formStateisSubmitSuccessfulboolean런타임 오류 없이 양식이 성공적으로 제출되었음을 나타냅니다.
formStateisSubmittingboolean현재 제출중일때 true
formStateisLoadingboolean비동기 default values를 로딩하는 중인경우 true
formStatesubmitCountnumber제출된 수
formStateisValidbooleanform이 에러가 없으면 true(setError는 isValid값에 영향을 주지 않습니다.오직 전체 form의 유효성에 영향받습니다.)
formStateisValidatingbooleanvalidation동안에 true
formStateerrorsobjecterrors필드의 object. ErrorMessage컴포넌트로 에러메세지를 쉽게 표시 가능

예시

TEXT FILED

import * as React from "react";
import { useForm, useController, UseControllerProps } from "react-hook-form";

type FormValues = {
  FirstName: string;
};

function Input(props: UseControllerProps<FormValues>) {
  const { field, fieldState } = useController(props);

  return (
    <div>
      <input {...field} placeholder={props.name} />
      <p>{fieldState.isTouched && "Touched"}</p>
      <p>{fieldState.isDirty && "Dirty"}</p>
      <p>{fieldState.invalid ? "invalid" : "valid"}</p>
    </div>
  );
}

export default function App() {
  const { handleSubmit, control } = useForm<FormValues>({
    defaultValues: {
      FirstName: ""
    },
    mode: "onChange"
  });
  const onSubmit = (data: FormValues) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Input control={control} name="FirstName" rules={{ required: true }} />
      <input type="submit" />
    </form>
  );
}

Check Boxes

import * as React from "react";
import { useController, useForm } from "react-hook-form";

const Checkboxes = ({ options, control, name }) => {
  const { field } = useController({
    control,
    name
  });
  const [value, setValue] = React.useState(field.value || []);

  return (
    <>
      {options.map((option, index) => (
        <input
          onChange={(e) => {
            const valueCopy = [...value];

            // update checkbox value
            valueCopy[index] = e.target.checked ? e.target.value : null;

            // send data to react hook form
            field.onChange(valueCopy);

            // update local state
            setValue(valueCopy);
          }}
          key={option}
          checked={value.includes(option)}
          type="checkbox"
          value={option}
        />
      ))}
    </>
  );
};

export default function App() {
  const { register, handleSubmit, control } = useForm({
    defaultValues: {
      controlled: [],
      uncontrolled: []
    }
  });
  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <section>
        <h2>uncontrolled</h2>
        <input {...register("uncontrolled")} type="checkbox" value="A" />
        <input {...register("uncontrolled")} type="checkbox" value="B" />
        <input {...register("uncontrolled")} type="checkbox" value="C" />
      </section>

      <section>
        <h2>controlled</h2>
        <Checkboxes
          options={["a", "b", "c"]}
          control={control}
          name="controlled"
        />
      </section>
      <input type="submit" />
    </form>
  );
}

Tips

  • MUI, AntD, Chakra UI와 같은 external controlled components로 작업할 때 각 props의 기능을 인식하는 것이 중요합니다. 그것의 일은 입력을 감시하고, 보고하고, 그것의 가치를 설정하는 것이다.
    • onChange : 데이터를 hook form 으로 돌려보냄
    • onBlur: input의 상호작용(focus / blur) 을 알려줌
    • value: 인풋의 초기값, 업데이트값을 셋업
    • ref: 인풋이 error 에 의해 포커싱 될수 있게 함
    • name: 인풋에 유일한 이름을 줌

state를 host하고 useController와 결합해도 좋습니다.

const { field } = useController();
const [value, setValue] = useState(field.value);

onChange={(event) => {
  field.onChange(parseInt(event.target.value)) // data send back to hook form
  setValue(event.target.value) // UI state
}}

input을 다시 register 하지마세요. 이 커스텀 훅은 registration 프로세스를 처리하도록 설계되었습니다.

const { field } = useController({ name: 'test' })

<input {...field} /> // ✅
<input {...field} {...register('test')} /> // ❌ double up the registration

component마다 단일 useController를 사용하는 것이 이상적입니다. 둘 이상을 사용해야 하는 경우에는 prop의 이름을 변경해야 합니다.
대신 Controller 사용을 고려할 수 있습니다.

const { field: input } = useController({ name: 'test' })
const { field: checkbox } = useController({ name: 'test1' })

<input {...input} />
<input {...checkbox} />

0개의 댓글