이미지09
Coding Story/REACT

[ React ] 리액트 React-Hook-Form

반응형

 

 

 

만약 프로젝트에서 리액트를 사용한다면 아주 작은 사이즈의 프로젝트가 아닌 이상,

 

폼 양식을 사용하지 않는 프로젝트는 드물 것이다.

 

하지만 리액트만으로 Input Validation, Form Submit 등 폼 관리를 하기엔 너무 고단하다.

 

이러한 문제점을 위해 보다 적은 코드양으로 쉽게 작성할 수 있는 라이브러리가 존재하는데,

 

그것이 React-Hook-Form 이다.

 

React-Hook-Form 을 사용하기 위해 아래와 같이 설치해야 함.

yarn add react-hook-form

 

저번 포스팅에서 다루었던 BoardNew.js 컴포넌트를 위주로 훅 폼을 적용시켜 살펴본다.

 

( 현 포스팅만 봐도 무방하다. )

 

 

 

 

먼저 기존의 BoardNew.js 코드는 아래처럼 되어있다.

import React from 'react';

function BoardNew({ changeInput, inputData, onSaveButtonClick, resetForm }) {

    const saveBtnClick = (e) => {
        e.preventDefault();
        onSaveButtonClick(inputData);
        resetForm();
    }

    return (
        <div>
            <form onSubmit={saveBtnClick}>
                <div>
                    제목 : <input type="text" name="boardTitle" onChange={changeInput} value={inputData.boardTitle} />
                </div>
                <div>
                    내용 : <input type="text" name="boardContent"  onChange={changeInput} value={inputData.boardContent} />
                </div>
                <input type="hidden" name="boardId" onChange={changeInput} value={inputData.boardId} />
                <button type="submit" >저장</button>
            </form>
        </div>
    )
};

export default BoardNew;

 

이전엔 위처럼 saveBtnClick 함수에 e.preventDefault() 를 걸어놨다.

 

이유는 a 태그나 submit 타입을 가진 버튼의 경우 이벤트 이외에 각자의 고유한 기능을 가지고 있는데,

 

우리가 선언한 이벤트 외에 페이지가 이동되버리거나 하면 곤란하니 이를 막기위해 걸어놓은 것이다.

 

하지만 React-Hook-FormhandleSubmit 을 이용하면 이를 해결가능하다.

 

 

 

 

handleSubmit 는 아래처럼 사용하면 된다.

import { useForm } from 'react-hook-form';
.
.
.
const { handleSubmit } = useForm();
.
.
.
return (
    <form onSubmit={handleSubmit()}>
    .
    .
    .
    </form>
)

 

 

BoardNew.js 를 아래와 같이 수정.

import React from 'react';
import { Button } from 'react-bootstrap';
import { useForm } from 'react-hook-form'; // react-hook-form import

function BoardNew({ changeInput, inputData, onSaveButtonClick, resetForm, onSearchButtonClick }) {

    const { handleSubmit } = useForm(); // useForm 의 handleSubmit 가져옴.

    const saveBtnClick = () => { // preventDefault() 제거
        onSaveButtonClick(inputData);
        resetForm();
    }

    return (
        <div>
            {/* saveBtnClick 을 handleSubmit 으로 감쌈 */}
            <form onSubmit={handleSubmit(saveBtnClick)}>
                <h3></h3>
                <div>
                    제목 : <input type="text" name="boardTitle" onChange={changeInput} value={inputData.boardTitle} />
                </div>
                <div>
                    내용 : <input type="text" name="boardContent" onChange={changeInput} value={inputData.boardContent} />
                </div>
                <input type="hidden" name="boardId" onChange={changeInput} value={inputData.boardId} />
                <div>
                <h3></h3>
                <Button color="red"onClick={onSearchButtonClick}>조회</Button>
                <Button type="submit" >저장</Button>
                </div>
            </form>
        </div>
    )
};

export default BoardNew;

 

기존의 preventDefault() 가 제거된 것을 확인할 수 있다.

 

또한 기존에는 저장 버튼을 클릭하면 바로 saveBtnClick() 를 실행했지만,

 

이젠 전송하기 전에 데이터 검증 및 추가적인 작업이 가능하게 되었다.

 

자, 그럼 방금 말한 데이터 검증에 대해 알아보기 위해 바로 넘어가도록 하자.

 

( 데이터 검증 또한 추가적인 작업이기에 )

 

 

React-Hook-Form 은 데이터 검증을 보다 간단하게 하는 등의,

 

input 값 관리를 쉽게 해주는 register 를 지원한다.

 

 

아래와 같이 useForm 에서 register 를 추가로 할당하고,

const { handleSubmit, register } = useForm();

 

 

기존의 input 태그에 아래와 같이 ref = { register ( { ... } ) } 추가.

<div>
    제목 : <input type="text" name="boardTitle" ref={register({ required: true })} onChange={changeInput} value={inputData.boardTitle} />
</div>
<div>
    내용 : <input type="text" name="boardContent" ref={register({required: true, minLength: 5})} onChange={changeInput} value={inputData.boardContent} />
</div>

 

register 는 Validation 을 보다 쉽게 관리 할 수 있도록 해주는데,

 

boardTitle input 내의 required 는 필수 값 체크를 해주고,

 

boardContent 내의 minLength 는 입력 값의 최소 길이 체크를 해준다.

 

이러한 Validation 을 언제 해주느냐? 이전에 선언한 handleSubmit 이 수행될 때 Validation Check 해준다.

 

 

실행 결과는 다음과 같다.

이미지1

 

 

만약 제목 입력란에 아무런 값을 입력하지 않고 저장을 누르면?

이미지2

require 검증에 걸려 제목란에 포커싱이 잡히게 되고, 저장 기능을 수행하지 않는다.

 

이 외에도 require 는 max, min, pattern 등을 가지고 있는데 여기를 참고하면 된당.

 

그럼 이러한 검증 등에 의해 error 가 발생했을 경우 이를 다루는 방법을 살펴보자.

 

 

아래와 같이 useForm 에서 errors 를 추가로 할당한다.

const { handleSubmit, register, errors } = useForm();

 

 

현재 Validation 은 제목은 필수 값 체크, 내용은 필수 값 체크와 입력길이 5 글자 이상이 걸려있다.

 

아무 위치에 console.log(errors) 를 입력한 뒤,

 

제목에 아무런 값을 입력하지 않고 내용은 두 글자만 입력 후 저장을 눌려 콘솔을 확인해보자.

 

이처럼 errors 검증에 실패한 input name 과, 어떤 검증에 실패했는지 알 수 있는 type 등을 가지고 있다.

 

 

이러한 errors 를 가지고 아래와 같이 추가적인 작업도 가능하다.

return (
        <div>
            <form onSubmit={handleSubmit(saveBtnClick)}>
                <h3></h3>
                <div>
                    제목 : <input type="text" name="boardTitle" ref={register({ required: true })} onChange={changeInput} value={inputData.boardTitle} />
                    {errors.boardTitle && '제목을 입력해주세요'}
                </div>
                <div>
                    내용 : <input type="text" name="boardContent"  ref={register({required: true, minLength: 5})} onChange={changeInput} value={inputData.boardContent} />
                    {errors.boardContent && (errors.boardContent.type == 'required' && '내용을 입력해주세요') || '최소 5글자 입력해주세요'}
                </div>
                <input type="hidden" name="boardId" onChange={changeInput} value={inputData.boardId} />
                <div>
                <h3></h3>
                <Button color="red"onClick={onSearchButtonClick}>조회</Button>
                <Button type="submit" >저장</Button>
                </div>
            </form>
        </div>
    )

 

 

이를 실행하고 제목에는 값을 입력하지 않고, 내용에는 두 글자만 입력하고 저장을 해보면?

이미지3

 

 

이렇게 handleSubmit 을 중점으로 register 와 errors 를 운용 가능한 useForm().

 

이를 이용하면 보다 간단하게 input 값을 관리할 수 있으니 써보는걸 추천드린당.

 

 

마지막으로 추가 Tip 을 드리자면 handleSubmit 으로 호출하는 사용자 함수는 input 입력 값을 받을 수도 있다.

 

아래처럼 콘솔을 추가하고,

const saveBtnClick = (data) => { // 이렇게 인자를 받고
    console.log(data); // 콘솔을 찍어보면 data 에 input 값이 나온다.
    .
    .
    .
}

return (
    <div>
        <form onSubmit={handleSubmit(saveBtnClick)}>
        .
        .
        .
)

 

 

실행시킨 뒤 아래처럼 input 값을 입력하고,

이미지4

 

 

저장 버튼을 눌리면 아래처럼 콘솔에 data 가 찍힌다.

이미지5

 

 

지금까지 말한 방법 이외에도 React-Hook-Form 은 어떻게 쓰냐에 따라 

 

할 수 있는 일이 무궁무진해진다. 계속 써봐야겠당. ㅎ

 

 

반응형