사용자 정의 훅은 use라는 접두사로 시작하며, 내부에서 다른 훅들이나 로직을 활용할 수 있습니다. 예를 들어, 상태 관리를 위한 훅인 useState나 데이터 가져오기를 위한 훅인 useEffect를 사용하여 사용자 정의 훅을 작성할 수 있습니다.
사용자 정의 훅은 함수 컴포넌트 내부에서 정의되며, 컴포넌트 내부에서 호출하여 사용됩니다. 이렇게 정의된 훅은 컴포넌트에서 사용되는 상태(state), 이벤트 핸들러, 비동기 로직 등을 추상화하여 편리하게 사용할 수 있습니다
// 이름을 입력하는 input
const [enterdName,setEnterdName] = useState('');
// 이름을 입력하는 input을 클릭했는지 확인
const [enterdNameTouched,setEnterdNameTouched] = useState(false);
// 이메일을 입력하는 input
const [enterdEmail,setEnterdEmail] = useState('');
// 이메일을 입력하는 input을 클릭했는지 확인
const [enterdEmailTouched,setEnterdEmailTouched] = useState(false);
// 이름에 대한 유효성 검사를 실행
const enterdNameIsValid = enterdName.trim() !== '';
// 이름에 대한 유효성 검사와 name input을 클릭했는지 여부를 통해
// name input창에 에러를 상활에 맞게 표시한다.
const nameInputIsValid = !enterdNameIsValid && enterdNameTouched;
// 이메일에 대한 유효성 검사를 실행
const enterdEmailIsValid = emailValidation(enterdEmail);
// 이메일에 대한 유효성 검사와 email input을 클릭했는지 여부를 통해
// email input창에 에러를 상활에 맞게 표시한다.
const emailInputIsValid = !enterdEmailIsValid && enterdEmailTouched;
// name input에 값을 실시간으로 바꾸고 클릭 했으니 true로 변경
const nameInputChangeHandler = (event) =>{
setEnterdName(event.target.value);
setEnterdNameTouched(true);
}
// onBlur에 함수를 넣어주고 포커스를 받고 빠지게 되면 true로 변경한다.
const nameInputBlurHandler = (event) =>{
setEnterdNameTouched(true);
}
// email input에 값을 실시간으로 바꾸고 클릭 했으니 true로 변경
const emailInputChangeHandler = (event) =>{
setEnterdEmail(event.target.value);
setEnterdEmailTouched(true);
}
// onBlur에 함수를 넣어주고 포커스를 받고 빠지게 되면 true로 변경한다.
const emailInputBlurHandler = (event) =>{
setEnterdEmailTouched(true);
}
이렇게 간단한 로직이라도 컴포넌트에 들어가는 코드의 양이 길어지고 중복되는 코드들이 너무 많기 때문에 사용자 정의 훅을 사용한다
// useInput.js
import { useState } from 'react'
// validateValue 로 검사할 로직의 함수를 보낸다.
const useInput = (validateValue) =>{
const [enterdValue,setEnterdValue] = useState('');
const [isTouched,setIsTouched] = useState(false);
const valueChangeHandler = (event) =>{
setEnterdValue(event.target.value);
}
const inputBlurHandler = (event) =>{
setIsTouched(true);
}
const reset = () =>{
setEnterdValue('');
setIsTouched(false);
}
const valueIsValid = validateValue(enterdValue);
const hasError = !valueIsValid && isTouched;
return {
value: enterdValue,
isValid: valueIsValid,
hasError,
reset,
valueChangeHandler,
inputBlurHandler
}
}
export default useInput;
// 컴포넌트.js
import useInput from '../hooks/use-input';
const {
value: enterdName, // 이런식으로 받는 쪽에서 하면 enterdName로 retrun 받는 값을 할당 받겠다는 의미이다.
isValid: enterdNameIsValid,
hasError: nameInputHasError,
valueChangeHandler: nameChangeHandler,
inputBlurHandler: nameBlurHandler,
reset: resetNameInput,
} = useInput((value) => value.trim() !== '');
const {
value: enterdEmail,
isValid: enterdEmailIsValid,
hasError: emailInputHasError,
valueChangeHandler: emailChangeHandler,
inputBlurHandler: emailBlurHandler,
reset: resetEmailInput,
} = useInput((value) => emailValidation(value));
이렇게 중복된 로직을 사용자 정의 훅을 통해 중복코드를 줄이고 같은 기능을 구현할 수 있다.