비제어 컴포넌트, React-hook-form

Jayden ·2024년 5월 18일

1. 비제어(Uncotrolled) 컴포넌트

리액트에는 텍스트 필드(input 태그로) 입력시 state로 컴포넌트의 상태값을 관리합니다.


const [text, setText] = useState('')


const handleText = (e) => {
  e.preventDefault();
  // sumbit 이벤트 발생시 페이지 새로고침 현상 방지
  console.log('제출 버튼 클릭');
}



return(
  <form onSubmit={handleText}>
 	<input value={text} onChange={(e) => setText(e.target.value)}/> 
	<button>제출</button>
  </form>
)

위와 같이 리액트에서 값을 관리하는 폼 요소를 제어 컴포넌트라고 합니다.

하지만 상태값이 변경될때마다 컴포넌트가 매번 렌더링되는 이슈가 발생합니다. 이를 방지하기 위해서
비제어 방식의 react-hook-form 라이브러리를 활용하여 폼을 관리할 수 있고 유효성 체크를 진행할 수 있습니다.

2. register 함수로 form 관리

register 함수는 useForm 함수에서 가져와 사용할 수 있습니다.

   const {register, handleSubmit} = useForm<any>({mode : "onChange"});


	const phoneSubmit = async (data : any) => {


        console.log(data)
        /*
            {
                phone : '0101234567' 
            }
		*/
    }
   return(
     <form onSubmit={handleSubmit(phoneSubmit)}>
     	<input {...register("phone")}/>
		<button>제출</button>
	 </form>
     )

     /*
     
     	<input {...register('firstName')} />는 아래와 동일한 의미
     	        
        <input 
          onChange={onChange} 
          onBlur={onBlur} 
          name={name} 
          ref={ref} 
        /> 
     */
     
  • mode : onChange 이벤트 사용 : 입력할때마다 유효성 체크 => 유효성 만족 안할 경우 에러 메시지 출력

  • required : 해당 필드가 유효성을 만족해야 최종적으로 inValid가 true로 적용.

  • patten : value 유효성 만족 조건을 정규식으로 작성, message에 유효성을 만족하지 않을 경우 표시할 에러 메시지 정의

import { styled } from "styled-components"
import { useForm } from "react-hook-form"

export default function Password(){

    const regexSpecialSign = /[{}[\]\/?.,;:|)*~`!^_+<>@#$%&\\=('""]/g; // 특수문자

    const {register, handleSubmit, watch, formState : {isValid, errors}} = useForm<any>({mode : "onChange"});
  
  
  const changePwordSubmit = async (data : any) => {


        const body = {
            ...data, 
            param1 : sessionStorage.getItem("param1")
        }
        
        // 이곳에 API 호출 로직 작성
  
    return(
            <form onSubmit={handleSubmit(changePwordSubmit)}>
                <div>
                    <h4>변경 패스워드</h4>
                    <input type ="password" 
                           style={{width : '300px', borderRadius : '10px'}}
                           placeholder={'영문자, 숫자 포함 6자 이상 12자 이하 사용'}
                                {...register('new_pw', {
                                    required : true,
                                    pattern : {
                                        value :  /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,12}$/,
                                        message : '잘못된 패스워드 입니다.'
                                    },
                                    onChange: (e) => {
                                        const value = e.target.value;
                                        const sanitizedValue = value.replace(regexSpecialSign, ''); // 패턴에 일치하는 문자열을 제거
                                        e.target.value = sanitizedValue; // 제거된 값을 다시 입력란에 할당
                                      },
                                })}
                    />
              
                        <p>{errors.new_pw && <span>{errors.new_pw.message}</span>}
                    </p>
					<button
                        disabled={!isValid}
						style={{backgroundColor : isValid ? 'red' : 'gray'}}>
                    </button>
                </div>
			</form>
profile
프론트엔드 개발자

0개의 댓글