[React] useForm Hook을 활용한 Input 관리 및 유효성 검사 구현 방법

woodylovesboota·2024년 1월 5일
0
post-thumbnail

기본적인 사용

1개의 input

const { register,handleSubmit, setValue } = useForm<IForm>();
const [inputData, setInputData] = useState("")

const onValid = (data: IForm) => {
  setInputData(data.keyword);
  setValue("keyword", "");
}

return (
  <Wrapper>
    <Form onSubmit={handleSubmit(onValid)}>
      <Input {...register("keyword", {required: true})} />
    </Form>
    <Result>
      Input Value is...{" "}
      {inputData && `"${inputData.keyword}"`}
    </Result>
  </Wrapper>
)

interface IForm {
  keyword: string;
}

여러개의 input
input의 이름을 다르게 해주면 한번여 여러개의 input을 다룰 수 있다.

const { register,handleSubmit, reset } = useForm<IForm>();
const [inputData, setInputData] = useState<IForm>()

const onValid = (data: IForm) => {
  setInputDate(data);
  reset();
}

return (
  <Wrapper>
    <Form onSubmit={handleSubmit(onValid)}>
      // 각각 다른 이름의 input
      <Input {...register("keyword1", {required: true})} />
      <Input {...register("keyword2", {required: true})} />
      <Input {...register("keyword3", {required: true})} />
    </Form>
    <Result>
      Input Value is...{" "}
      {inputData && `"${inputData.keyword1}, ${inputData.keyword2}, ${inputData.keyword3}"`}
    </Result>
  </Wrapper>
)

interface IForm {
  keyword1: string;
  keyword2: string;
  keyword3: string;
}

Error Handle

formState의 error를 이용하여 form의 유효성 검사를 처리할 수 있다.

const { register,handleSubmit, reset, formState: { errors } } = useForm<IForm>();
const [inputData, setInputData] = useState<IForm>()

const onValid = (data: IForm) => {
  setInputDate(data);
  reset();
}

return (
  <Wrapper>
    <Form onSubmit={handleSubmit(onValid)}>
      {errors.keyword1 && <Error>keyword1을 입력해주세요!</Error>}
      <Input {...register("keyword1", {required: true})} />
      {errors.keyword2 && <Error>keyword2을 입력해주세요!</Error>}
      <Input {...register("keyword2", {required: true})} />
      {errors.keyword3 && <Error>keyword3을 입력해주세요!</Error>}
      <Input {...register("keyword3", {required: true})} />
    </Form>
    <Result>
      Input Value is...{" "}
      {inputData && `"${inputData.keyword1}, ${inputData.keyword2}, ${inputData.keyword3}"`}
    </Result>
  </Wrapper>
)

interface IForm {
  keyword1: string;
  keyword2: string;
  keyword3: string;
}

동적인 input 관리

useFieldArray를 이용하여 input의 개수를 동적으로 관리할 수 있다.

const { register,handleSubmit, reset, control } = useForm<IForm>({ defaultValues: { multiValues: [{ value: "" }] } });

const { fields, append, remove } = useFieldArray({ control, name: "multiValues" });

interface IForm {
  keyword1: string;
  keyword2: string;
  keyword3: string;
  multiValues: { value: string; }[];
}

...
return (
  ...
  {fields.map((field, index) => (
    <Multi key={field.id}>
      <Title>Value {index + 1}</Title>
      <Input {...register(`multiValues.${index}.value`, { required: true })} />
      <DeleteRowButton type="button" onClick={() => remove(index)}>
        <IconWrapper>
          <FontAwesomeIcon icon={faMinus} />
        </IconWrapper>
      </DeleteRowButton>
    </Multi>
  ))}
)

다른 input들과 함께 사용할 수 도 있고, 동적인 input 쌍으로 관리할 수 도 있다.

const { register,handleSubmit, reset, control } = useForm<IForm>({ defaultValues: { multiValues: [{ value: "", key: "" }] } });

const { fields, append, remove } = useFieldArray({ control, name: "multiValues" });

interface IForm {
  keyword1: string;
  keyword2: string;
  keyword3: string;
  multiValues: { value: string; key: string }[];
}

...
return (
  ...
  {fields.map((field, index) => (
    <Multi key={field.id}>
      <Title>Value {index + 1}</Title>
      <Input {...register(`multiValues.${index}.value`, { required: true })} />
      <Title>Key {index + 1}</Title>
      <Input {...register(`multiValues.${index}.key`, { required: true })} />
      <DeleteRowButton type="button" onClick={() => remove(index)}>
        <IconWrapper>
          <FontAwesomeIcon icon={faMinus} />
        </IconWrapper>
      </DeleteRowButton>
    </Multi>
  ))}
)

0개의 댓글