커스텀 훅(Custom Hook)은 이름이 use
로 시작하는 자바스크립트 함수입니다.
이름 그대로 사용자의 입맛에 맞춰서 커스텀해서 사용합니다.
예시 코드입니다.
const UserStatus = () => {
const [isActive, setIsActive] = useState(false);
const handleToggle = () => {
setIsActive((prev) => !prev);
};
return (
<>
<h1>현재 사용자의 상태입니다.</h1>
<span>{isActive ? '사용 중' : '사용 안 함'}</span>
<button onClick={handleToggle}>사용 상태 변경</button>
</>
);
};
위의 코드는 로직과 UI가 병합되어있는 코드입니다.
해당 코드를 커스텀훅을 사용해서 분리해보겠습니다.
const useToggle = (initialValue = false) => { // 1
const [state, setState] = useState(initialValue); // 2
const handleToggle = () => { // 3
setState((prev) => !prev);
};
return [state, handleToggle]; // 4
};
const UserStatus = () => {
const [isActive, changeStatus] = useToggle(); // 5
return (
<>
<h1>현재 사용자의 상태입니다.</h1>
<span>{isActive ? '사용 중' : '사용 안 함'}</span> // 6
<button onClick={changeStatus}>사용 상태 변경</button>
</>
);
};
useToggle
이라는 커스텀 훅을 만들고, 해당 훅을 UserStatus 라는 컴포넌트에서 사용하고있습니다.
이러한 커스텀 훅의 로직과 그것을 사용하는 컴포넌트의 UI가 모두 같은 파일에 존재하게 된다면
커스텀 훅을 두개, 혹은 그 이상 사용할 경우 한 파일에 굉장히 많은 코드가 존재하며 가독성이 떨어질 것입니다.
그래서 커스텀훅을 따로 분리합니다.
//useToggle.js (로직 부분 예시 코드)
import { useState } from 'react';
const useToggle = (initialValue = false) => {
const [state, setState] = useState(initialValue);
const handleToggle = () => {
setState((prev) => !prev);
};
return [state, handleToggle];
};
export default useToggle;
// ./UserStatus.js (UI 부분 예시 코드)
import React from 'react';
import useToggle from './useToggle';
const UserStatus = () => {
const [isActive, changeStatus] = useToggle();
return (
<>
<h1>현재 사용자의 상태입니다.</h1>
<span>{isActive ? '사용 중' : '사용 안 함'}</span>
<button onClick={changeStatus}>사용 상태 변경</button>
</>
);
};
export default UserStatus;
마치 useState , useRef , useNavigate
와 같이
기본적으로 제공되는 Hooks 를 사용하는 것 처럼 Import해서 사용합니다.
하지만 무조건 이런 식의 분리가 권장되는 것은 아닙니다.
과도한 파일 분리는 오히려 변경을 힘들게 만듭니다.
파일분리가 필요한 경우와 그렇지 않은 경우를 잘 판단하는 것이 중요합니다.