반응형

React Hook Form // https://react-hook-form.com/

 

React Hook Form - performant, flexible and extensible form library

Performant, flexible and extensible forms with easy-to-use validation.

react-hook-form.com

react hook form은 validation이나 에러, 이벤트 같은 필요한 기능들을 넣어서 적은 줄의 코드를 사용해 form을 만들 수 있게 해준다.

아래 코드는 기존 hoor form을 안쓰고 하는경우이다

"use client";
import {SyntheticEvent, use, useState} from "react";

export default function Form() {
  const [username, setUsername] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("")
  const [formErr, setFormErr] = useState("");
  const onUsernameChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
    const {
      currentTarget: {value},
    } = event;
    setUsername(value);
  };
  const onEmailChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
    const {
      currentTarget: {value},
    } = event;
    setEmail(value);
  };
  const onPasswordChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
    const {
      currentTarget: {value},
    } = event;
    setPassword(value);
  };
  const onSubmit = (event: SyntheticEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log(username, email, password);
    // validation codes..
        // validation codes..
            // validation codes..
                // validation codes..
                    // validation codes..
                        // validation codes..    // validation codes..
                        
  };
  return (
    <div>
      <form action="" onSubmit={onSubmit}>
        <input
          value={username}
          onChange={onUsernameChange}
          type="text"
          placeholder="Username"
          required
        />
        <input
          value={email}
          onChange={onEmailChange}
          type="email"
          placeholder="Email"
          required
        />
        <input
          value={password}
          onChange={onPasswordChange}
          type="password"
          placeholder="password"
          required
        />
        <input type="submit" value="submit"/>
      </form>
    </div>
  );
}

hook form을 사용하지 않게 되면 사용자가 html코드를 건드려 마음대로 설정할수 있다.

또한 좋은 form을 만들려다보면 스크립트 내에서의 validation을 검증하는 코드가 길어진다.

 

React Hook Form Install

npm install react-hook-form

 

How To Use?

1. register

첫번째로 해야할 것은 input을 state와 연결하는 것이다. 다음에 validation을 하고 다음에 err를 다룬다.

console.log(register)를 하게 되면 4가지를 사용할 수 있음을 볼 수 있다. name ,onBlur, onChange ,ref 이것들은 React에서 Input에 활용되는 attribute와 비슷하다.

"use client";

import {useForm} from "react-hook-form";

export default function Form() {
  const {register} = useForm();

  return (
    <div>
      <form>
        <input
          {...register("username")}
          type="text"
          placeholder="Username"
          required
        />
        <input
          {...register("email")}
          type="email"
          placeholder="Email"
          required
        />
        <input
          {...register("password")}
          type="password"
          placeholder="password"
          required
        />
        <input type="submit" value="submit" />
      </form>
    </div>
  );
}

 

2.  watch

"use client";

import {useForm} from "react-hook-form";

export default function Form() {
  const {register, watch} = useForm();
	console.log(watch())
	console.log(watch("email"))
    //원하는 것만 볼 수도 있다.
  return (
    <div>
      <form>
        <input
          {...register("username")}
          type="text"
          placeholder="Username"
          required
        />
        <input
          {...register("email")}
          type="email"
          placeholder="Email"
          required
        />
        <input
          {...register("password")}
          type="password"
          placeholder="password"
          required
        />
        <input type="submit" value="submit" />
      </form>
    </div>
  );
}

콘솔창을 열고 input에 값을 입력하면 register된 input의 값이 바로 변경하는것을 볼 수 있다.

3. validation

register의 두번째 인자로 validation Rule를 적을 수 있게 해준다.

"use client";

import {useForm} from "react-hook-form";

export default function Form() {
  const {register, watch} = useForm();
	console.log(watch())
  return (
    <div>
      <form>
        <input
          {...register("username",{
          required:true,
          })}
          type="text"
          placeholder="Username"
        />
        <input
          {...register("email",{
          required:"Email is Required",
          })}
          type="email"
          placeholder="Email"
        />
        <input
          {...register("password",{
          required:true,
          })}
          type="password"
          placeholder="password"
        />
        <input type="submit" value="submit" />
      </form>
    </div>
  );
}

4. handleSubmit

handleSubmit은 인자로 2개 또는 1개의 함수를 받을 것이다. 1개는 필수로 설정되어 있다.

첫번째 함수는 form이 유효할 때만 실행되는 함수

두번째 함수는 form이 유효하지 않을 때 실행되는 함수

"use client";
import {FieldErrors, useForm} from "react-hook-form";

interface ILoginForm {
  username: string;
  email: string;
  password: string;
}

export default function Form() {
  const {register, watch, handleSubmit} = useForm<ILoginForm>();
  console.log(watch());
  const onValid = (data: ILoginForm) => {
    console.log("OK");
  };
  const onInValid = (errors: FieldErrors) => {
    console.log(errors);
  };
  return (
    <div>
      <form onSubmit={handleSubmit(onValid, onInValid)}>
        <input
          {...register("username", {
            required: "Username is Required",
            minLength: 5,
          })}
          type="text"
          placeholder="Username"
        />
        <input
          {...register("email", {
            required: "Email is Required",
          })}
          type="email"
          placeholder="Email"
        />
        <input
          {...register("password", {
            required: "Password is Required",
            minLength: {
              message: "More Than 5",
              value: 5,
            },
          })}
          type="password"
          placeholder="password"
        />
        <input type="submit" value="submit" />
      </form>
    </div>
  );
}

 

5.formState & Others..

formState는 많은 걸 제공하는 객체인데 그중하나가 errors 이다.

errors로 validate error를 도출해낼수 있다. 

setValue는 이벤트를 통해 원하는 input에 값을 넣어줄 수 있다.

setError는 특정 필드에 대한 에러가 아니라 form에 대한 전체적인 에러를 얘기한다. 예를 들어 fetch를 통한 에러

reset은 submit을 동작하게 되면 input의 값들을 초기화하는 동작을 한다.

resetField는 특정 input값을 초기화 해준다

"use client";

import {FieldErrors, useForm} from "react-hook-form";

interface ILoginForm {
  username: string;
  email: string;
  password: string;
  errors?: string;
}
export default function Form() {
  const {
    register,
    watch,
    handleSubmit,
    formState: {errors},
    setValue,
    setError,
    reset,
    resetField,
  } = useForm<ILoginForm>({
    mode: "onBlur",
  });

  console.log(watch());

  const onValid = (data: ILoginForm) => {
    console.log("OK");
    setError("errors", {message: "backend is offline"});
    resetField("password");
  };
  const onInValid = (errors: FieldErrors) => {
    console.log(errors);
    reset();
  };

  return (
    <div>
      <form onSubmit={handleSubmit(onValid, onInValid)}>
        <input
          {...register("username", {
            required: "Username is Required",
            minLength: {
              message: "more than 5",
              value: 5,
            },
          })}
          type="text"
          placeholder="Username"
          className={`${Boolean(errors.username) ? "bg-red-400" : ""} 
           `}
        />
        <button
          type="button"
          onClick={() => {
            setValue("username", "hihihi");
          }}
        >
          push
        </button>
        <p>{errors.username?.message}</p>
        <input
          {...register("email", {
            required: "Email is Required",
            validate: {
              notGmail: (value) =>
                !value.includes("@gmail.com") || "Gmail is not allowed",
            },
          })}
          type="email"
          placeholder="Email"
        />
        {errors.email?.message}
        <input
          {...register("password", {
            required: "Password is Required",
            minLength: {
              message: "More Than 5",
              value: 5,
            },
          })}
          type="password"
          placeholder="password"
        />
        {errors.password?.message}
        <input type="submit" value="submit" />
        {errors.errors?.message}
      </form>
    </div>
  );
}

 

728x90

'React > React Hook Form' 카테고리의 다른 글

2023/08/31__React(ReactHookForm)  (2) 2023.08.31
반응형

React-Hook-Form

React Hook Form라이브러리를 사용하면 따로 이벤트 헨들러, state를 만들 필요가 없다.

// 기존

export default function Mainpage() {
  const [val, setVal] = useState("");
  const onChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: {value},
    } = event;
    setVal(value);
  };
  const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
     console.log("submit")
  };
  return (
    <div>
      <h1>React / Recoil / StyledComponent / TypeScript / To Do List</h1>
      <form onSubmit={onSubmit}>
        <input type="text" value={val} onChange={onChange} />
        <button>Add</button>
      </form>
    </div>
  );
}

1-1. register()

register 함수를 사용하면 onChange 이벤트 핸들러, props, state 가 필요가 없다.

register 함수에는 

  • name
  • onChnage
  • onBlur
  • ref

가 내포되어 있다.  react input의 attribute라고 생각되면 됨

1-2. watch()

watch는 form의 입력값들의 변화를 관찰 할 수 있게 해주는 함수

1-3. handleSubmit( onValid(required), onInValid(optional))

validation을 담당함 .  handleSubmit에는 2개의 인자를 받는데 하나는 데이터가 유효할 때 호출되는 함수

다른 하나는 실패했을 때 호출 되는 함수

1-4.formState

console.log(formState.errors)를 하게 되면 해당부분에 떤 에러가 났는지 디버깅 할수 있다.

interface IFormData {
  todo: string;
  email: string;
  errors: {
    email: {
      message: string;
    };
  };
}
export default function Mainpage() {
  const {
    register,
    watch,
    handleSubmit,
    formState: {errors},
  } = useForm<IFormData>();
  const onValid = (data: any) => {
    console.log(data);
  };

  return (
    <div>
      <h1>React / Recoil / StyledComponent / TypeScript / To Do List</h1>
      <form onSubmit={handleSubmit(onValid)}>
        {/* // register안에 required를 작성해 html의 소스코드를 보호할수 있다. */}
        <input
          {...register("todo", {
            required: true,
            minLength: {
              value: 5,
              message: "length is too short",
            },
          })}
          type="text"
          placeholder="Write a to do"
        />
        <input
          {...register("email", {
            required: "emai is required",
            minLength: 5,
            pattern: {
              value: /^[A-Za-z0-9._-]*@[A-za-z0-9]*\.[a-zA-Z]{2,3}$/,
              message: "only email",
            },
          })}
          type="email"
          placeholder="Write Email"
        />
        <span>{errors?.email?.message}</span>
        <button>Add</button>
      </form>
    </div>
  );
}

2. Custom Validation

  const onValid = (data: IFormData) => {
    if (data.pw !== data.pw1)
      setError("pw1", {message: "pw are not same"}, {shouldFocus: true});
    setError("extraError", {message: "server offline"});
  };
  
  // 코드 생략
  
   <input
          {...register("name", {
            required: true,
            minLength: {
              value: 5,
              message: "length is too short",
            },
            validate: {
              badName: (value) =>
                value.includes("fuck") ? "bad word is not allowd" : true,
            },
          })}
          type="text"
          placeholder="Write a name"
        />
        <span>{errors?.name?.message}</span>

 

728x90

'React > React Hook Form' 카테고리의 다른 글

React Hook Form  (0) 2023.11.15

+ Recent posts