
import { useState } from 'react';
const ToDoList = () => {
  const [toDo, setToDo] = useState('');
  const [toDoError, setToDoError] = useState('');
  const onChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setToDoError('');
    setToDo(value);
  };
  const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log(toDo);
    if (toDo.length < 10) {
      return setToDoError('To do should be longer');
    }
    console.log('submit');
  };
  return (
    <>
      <div>
        <form onSubmit={onSubmit}>
          <input onChange={onChange} value={toDo} placeholder="Write a to do" />
          <button>Add</button>
          {toDoError !== '' ? toDoError : null}
        </form>
      </div>
    </>
  );
};
export default ToDoList;
npm install react-hook-form
import { useForm } from 'react-hook-form';
const ToDoList = () => {
  const {} = useForm();
  return (
    <>
      <div>
        <form>
          <input placeholder="Write a to do" />
          <button>Add</button>
        </form>
      </div>
    </>
  );
};
export default ToDoList;
const {} = useForm() 에서 다양한 메서드(도구)를 사용할 수 있다.register: 입력 요소를 폼에 등록하는 함수handleSubmit: 폼 제출을 처리하는 함수formState: 폼의 상태에 관한 정보를 담고 있다. (예: errors)setError: 수동으로 폼의 오류를 설정하는 함수setValue : 폼 제출 후 입력값을 설정하는 함수import { useForm } from 'react-hook-form';
const ToDoList = () => {
  const { register } = useForm();
  return (
    <>
      <div>
        <form>
          <input {...register('toDo')} placeholder="Write a to do" />
          <button>Add</button>
        </form>
      </div>
    </>
  );
};
export default ToDoList;
input {...register('toDO')}한번으로 전부 적용할 수 있다.<input
  {...register('email', {
    required: 'Email is required',
    minLength: 10,
    pattern: {
      value: /^[A-Za-z0-9._%+-]+@naver.com$/,
      message: 'Only naver.com emails allowed',
    },
  })}
  placeholder="Email"
/>const ToDoList = () => {
  const { register, watch } = useForm();
console.log(watch())
유효하다면 해당 콜백 함수를 실행한다.import { useForm } from 'react-hook-form';
const ToDoList = () => {
  const { register, handleSubmit } = useForm();
  // 모든 검증이 끝나면 일어난다.
  const onVaild = (data: any) => {
    console.log(data);
  };
  return (
    <>
      <div>
        <form onSubmit={handleSubmit(onVaild)}>
          <input {...register('email')} placeholder="email" />
          <input {...register('firstName')} placeholder="firstName" />
          <input {...register('lastName')} placeholder="lastName" />
          <input {...register('userName')} placeholder="userName" />
          <input {...register('password')} placeholder="password" />
          <button>Add</button>
        </form>
      </div>
    </>
  );
};
export default ToDoList;
isDirty: 사용자가 폼의 어떤 입력 필드라도 변경한 경우 true를 반환isSubmitting: 폼이 현재 제출 중인 경우 true를 반환isValid: 폼이 유효한 경우 true를 반환submitCount: 폼이 제출된 횟수touchedFields: 사용자가 접근하거나 수정한 입력 필드의 목록errors: 폼의 유효성 검사 오류에 대한 정보.import { useForm } from 'react-hook-form';
const ToDoList = () => {
  const { register, handleSubmit, formState } = useForm();
  // 모든 검증이 끝나면 일어난다.
  const onValid = (data: any) => {
    // console.log(data);
  };
  // formState의 errors 속성 확인
  console.log(formState.errors);
  return (
    <>
      <div>
        <form
          style={{ display: 'flex', flexDirection: 'column' }}
          onSubmit={handleSubmit(onValid)}
        >
          <input
            {...register('email', { required: true })}
            placeholder="email"
          />
          <input
            {...register('firstName', { required: true, minLength: 10 })}
            placeholder="firstName"
          />
          <input
            {...register('lastName', { required: true })}
            placeholder="lastName"
          />
          <input
            {...register('userName', { required: true })}
            placeholder="userName"
          />
          <input
            {...register('password', {
              required: 'Password is required',
              minLength: {
                value: 5,
                message: 'Your password too short',
              },
            })}
            placeholder="password"
          />
          <button>Add</button>
        </form>
      </div>
    </>
  );
};
export default ToDoList;
type : 오류의 유형. (예: "required", "minLength", "pattern" 등)message : 오류에 대한 메시지. register 함수에서 설정한 오류 메시지나 setError 함수를 통해 수동으로 설정한 오류 메시지를 포함할 수 있다.
API 응답 또는 사용자 정의 로직을 기반으로 오류를 설정할 때 유용하다.setError(name, error, options);
type: 오류의 유형 (예: "manual", "required" 등)message: 오류 메시지shouldFocus: 오류가 설정된 입력 필드로 포커스를 이동할지 결정하는 불리언 값.const onValid = (data: IForm) => {
    if (data.password !== data.rePassword) {
      setError(
        'rePassword',
        { message: 'Password are not the same' },
        { shouldFocus: true },
      );
    }
  };
register 함수의 validate 옵션을 사용해서 정의할 수 있다.
pattern은 정규 표현식을 기반으로 입력 값의 형식을 검사한다.pattern 속성의 값은 정규 표현식과 관련된 오류 메시지를 포함하는 객체가 될 수 있다.예시:
register('email', {
  pattern: {
    value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
    message: 'Invalid email format'
  }
})
validate는 사용자 정의 검증 함수를 제공하여 좀 더 복잡한 유효성 검사를 수행할 수 있다.true 또는 유효하지 않은 경우 오류 메시지를 반환해야 한다.예시:
register('username', {
  validate: {
    isUnique: value => isUsernameUnique(value) || 'Username is already taken',
    notEmpty: value => value.trim().length > 0 || 'Username cannot be empty'
  }
})
pattern은 정규 표현식을 기반으로 입력 값의 형식을 간단하게 검사하는 데 사용되는 반면, validate는 복잡한 로직이나 여러 검증 규칙을 적용하는 데 사용된다.pattern은 주로 특정 형식의 값이 입력되었는지 확인하는 데 사용되고, validate는 다양한 조건을 기반으로 입력 값을 검증하는 데 사용된다.