0. 현재 졸작 프로젝트에서 form을 입력 받는 코드는 가히 끔찍하다고 말할 수 있다.

     

    1. react-hook-form 라이브러리를 사용하면 form을 만들때 onChange, onSubmit을 여러개 만들어야 하는 과정을 단순화 하고,  조건 검사과정도 단순화해준다.

     

    2. 사용과정

    npm i react-hook-form

    import {useForm} from "react-hook-form";
    
    const {register} = useForm();

    register() 함수는 특정 문자열을 인자로 받으면 객체를 반환한다,

    반환한 객체 내부에는 인자가 name의 key value로 들어가있다.

     

    또 onChange와 onBlur함수가 있는데, 일단 blur란, input의 focus에서 벗어날 때를 말한다.

    이후 아래와 같이 input의 props로 spread 해준다.

    <input {...register("고유Name")} placeholder="Write a to do" />

     

    *ES6인 Spread operator ... 은 배열, 문자열, 객체 등 전개 가능한 요소들을 key-value형태로(?) 전개해준다.

    const numbers = [1, 2, 3, 4, 5, 6];
    
    const [one, two, ...rest] = numbers;
    
    //결과 : rest에 3,4,5,6이 들어감

     

    어쨋든 이후 register로 입력받은 값은 watch 함수로 확인해준다,

    const {register, watch} = useForm();
    console.log(watch());

    input이 많아질 때 빛을 내는 라이브러리이다.

     

    <input {...register("id")} placeholder="Write a to do" />
    <input {...register("비번")} placeholder="Write a to do" />
    <input {...register("비번확인")} placeholder="Write a to do" />
    <input {...register("이름")} placeholder="Write a to do" />
    <input {...register("생일")} placeholder="Write a to do" />

     

     

    3. submit 이벤트 대체 - submit form validation 도 쉽게 설정하기

     

    handleSubmit 함수를 사용한다.

    const {register, watch, handleSubmit} = useForm();
        function onValid(data){
    		console.log(data)
        }
        ...
        return <div>
            <form onSubmit={handleSubmit(onValid)}>
            ...

    handleSubmit은 Promise함수의 구조와 유사하게 인자로 성공했을 때 실행할 콜백함수, 실패했을때 실행할 콜백함수를 받는다.

     

    data 내부에 submit시 받는 모든 form의 값들이 object로 들어감.

     

    또 주목할 점은, onSubmit 내부에 실행하는 함수를 적어둔다는 것이다.

     

     

    4. required 선에서 HTML의 보호는 유저가 html을 수정하면 지켜지지 않을 수 있다.

    따라서 JS 선에서 validation이 필요하다.

    <input {...register("Id", {required:true})} placeholder="Write a to do" />

    최소 글자 수 minLength, 최대 글자수 maxLength 등등이 있다.

     

    또 true 자리에 문자열을 넣으면 에러 object에 에러 메세지를 보낼 수 있다.

    <input {...register("Id", {required:"필수 입력 항목입니다"})} placeholder="Write a to do" />

    minlength 또한

    minLength:{
    	value: 5,
        message:""
    }

    형태로 쓸 수 있다. 자세한 것은 5에서.

     

    +regular expression 정규 표현식 사용하기

    /^[A-Za-z0-9._%+-]
    
    //대소문자 영어, 숫자, 기호

    위 정규 표현식을 validation에 넣어주려면 pattern이라는 옵션에 넣는다.

    <input {...register("Id", {required:"필수 입력 항목입니다",
    pattern:{value:/^(정규표현식)},
    		message:"에러 메세지"})} placeholder="Write a to do" />

    form error 자동 처리하기

    formState 라는 함수를 사용한다.

    아래가 풀 코드

    interface IFormData{
        error:{
            id:{
                message:string;
            }
        }
        //만약 id가 필수 입력이 아니면 id?:string
        id:string;
    }
    
    function ToDoList(){
        const {register, watch, handleSubmit, formState:{errors}} = useForm<IFormData>(
        {
        	defaultValues:{
            	id:"시작하자 가지는 값."
            }
        });
        function onValid(data: IFormData){
    
        }
        console.log(watch());
        return <div>
            <form onSubmit={handleSubmit(onValid)}>
                <input {...register("id", {required:"Email is required"})} placeholder="Write a to do" />
                <h3>
                    {errors?.id?.message}
                </h3>
                <button>add</button>
            </form>
        </div>;
    }

     

    5. custom error 다루기

    setError 함수를 사용한다.

     

    form이 정상 제출되었을 때 실행되는 onValid함수 안에서 한번 더 가로막는 식으로 진행.

    여기서 다 통과했을 때 백엔드로 보내주면 될 듯하다.

     

    interface IFormData{
        error:{
            id:{
                message:string;
            }
        }
        id:string;
        pwd1: string;
        pwd2: string;
    }
    
    function ToDoList(){
        const {register, watch, handleSubmit, formState:{errors}, setError} = useForm<IFormData>();
        function onValid(data: IFormData){
            if(data.pwd1 !== data.pwd2){
                setError("pwd1", {message:"pwd are not same"},{shouldFocus:true});
            }
            //서버 반응 없음 조건으로
            //setError("extraError", {message:"Server offline"});
        }
        console.log(watch());
        return <div>
            <form onSubmit={handleSubmit(onValid)}>
                <input {...register("id", {required:"Email is required"})} placeholder="Write a to do" />
                <h3>
                    {errors?.id?.message}
                </h3>
                <input {...register("pwd1", {required:"pwd is required"})} />
                <input {...register("pwd2", {required:"pwd is required"})} />
                <h3>
                    {errors?.pwd1?.message}
                </h3>
                <button>add</button>
            </form>
        </div>;
    }

    shouldFocus 옵션: 에러난 지점에 focus 옮겨주기

     

    각 input에 validate 옵션을 추가해서 조건 검사를 추가할 수 있음

    validate는 value를 인자로 가지는 함수를 받는다

    <input {...register("id", {required:"Email is required"
            , validate:(value) => value.includes("sample") ? "에러 문자열 반환": true})} />
            
    //서버를 이용한다면 비동기 처리
    <input {...register("id", {required:"Email is required"
            , validate: async (value) => value.includes("sample") ? "에러 문자열 반환": true})} />

    validate는 객체 형태로 검사 함수를 여러개 받을 수 있다.

    key-value 형태로 함수명-함수 형태로 입력받는다.

     

    추가로

    setValue 함수를 통해 input에 값을 넣어줄수도 있다.

    setValue("name", "value") 구조이다.

    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기