React Custom Hooks
리액트 훅을 사용하다 보면, useState, useEffect, useRef 등 반복되는 로직이 여러 컴포넌트에 등장하는 경우가 많습니다. 이때 공통 로직을 재사용하고, 컴포넌트는 UI에만 집중할 수 있도록 도와주는 것이 바로 커스텀 훅(Custom Hook)입니다.
1. 커스텀 훅이란?
커스텀 훅은 이름 그대로 개발자가 직접 정의한 훅 함수입니다. 내부적으로는 useState, useEffect 등 기존 훅을 사용해 공통 로직을 추상화합니다.
규칙
- 이름은 반드시 use로 시작해야 합니다 (useMyHook)
- 일반 함수지만 훅 규칙(Hooks Rules)을 따라야 합니다
- 최상위에서만 호출
- 조건문이나 반복문 안에서는 호출하지 말 것
2. 간단한 예제
a. 윈도우 크기 추적 훅
i. 기존 방식 (중복되는 코드)
function MyComponent() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return <div>너비: {width}px</div>;
}
ii. 기존 방식을 커스텀 훅으로 구현
// useWindowWidth.js
import { useState, useEffect } from 'react';
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
export default useWindowWidth;
iii. 추출한 커스텀 훅을 사용
import useWindowWidth from './useWindowWidth';
function MyComponent() {
const width = useWindowWidth();
return <div>현재 창 너비: {width}px</div>;
}
- 커스텀 훅을 만들면 중복 코드 제거, 테스트 용이성 증가, 가독성 향상 등의 이점을 얻을 수 있습니다.
b. API 데이터 패칭 훅
커스텀 훅은 단순 값 추적 뿐 아니라, 입력 검증, API 요청, 폼 관리 등 다양한 기능을 담을 수 있습니다.
i. 커스텀 훅 구현
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
let isMounted = true;
fetch(url)
.then((res) => res.json())
.then((result) => {
if (isMounted) {
setData(result);
setLoading(false);
}
})
.catch((err) => {
if (isMounted) {
setError(err);
setLoading(false);
}
});
return () => {
isMounted = false;
};
}, [url]);
return { data, loading, error };
}
import useWindowWidth from './useWindowWidth';
function MyComponent() {
const width = useWindowWidth();
return <div>현재 창 너비: {width}px</div>;
}
3. 커스텀 훅 모범 사례
항목 | 설명 |
단일 책임 원칙 | 훅은 하나의 기능만 담당하게 구성 (useForm, useTimer, useAuth) |
이름에 의미 부여 | useFetch, useScroll, useDarkMode 등 기능이 명확하게 드러나야 함 |
조건 없는 호출 | 훅은 항상 컴포넌트 최상단에서 호출해야 함 |
훅 안에서 훅 사용 가능 | 커스텀 훅 내부에서도 다른 훅(useState, useEffect) 사용 가능 |
4. 커스텀 훅과 훅 생태계
많은 오픈소스 라이브러리들도 커스텀 훅을 제공합니다.
- React Query → useQuery, useMutation
- SWR → useSWR
- Formik → useFormik
- React Hook Form → useForm
커스텀 훅을 잘 만들고 잘 활용하는 건 리액트 개발의 생산성과 품질을 끌어올리는 핵심 기술입니다.
5. 마무리
커스텀 훅은 단순한 코드 추출을 넘어서, 리액트 앱의 로직 분리, 유지보수성, 테스트성, 가독성을 크게 향상시켜 줍니다. 반복되는 로직이 있다면 주저 말고 훅으로 분리해보세요. 리액트스러운 설계가 무엇인지 몸소 느낄 수 있을 거예요.
함께 보면 좋은 자료
블로그 글 :
[React Hooks] useState부터 커스텀 훅까지
React HooksReact 16.8부터 등장한 Hooks(훅)은 함수형 컴포넌트에서도 상태 관리와 사이드 이펙트를 다룰 수 있게 해주며, 컴포넌트 구조를 더욱 직관적으로 바꿨습니다. 이 글에서는 자주 사용되는 기
dachaes-devlogs.tistory.com
[Advanced React Hooks] useReducer부터 useImperativeHandle까지
Advanced React HooksReact를 어느 정도 사용해본 개발자라면 useState, useEffect 같은 기본 훅은 익숙할 것입니다. 하지만 복잡한 상태 관리나 라이프사이클 제어, 퍼포먼스 개선 등 더 세밀한 제어가 필
dachaes-devlogs.tistory.com
'프레임워크와 라이브러리 > React' 카테고리의 다른 글
[useCallback] 불필요한 리렌더링 줄이기 (0) | 2025.04.18 |
---|---|
[key] 리액트에서 key로 index를 쓰면 안 되는 이유 (0) | 2025.04.16 |
[클래스 컴포넌트와 함수 컴포넌트] 리액트의 컴포넌트 (0) | 2025.04.15 |
[Advanced React Hooks] useReducer부터 useImperativeHandle까지 (0) | 2025.04.11 |
[React Hooks] useState부터 커스텀 훅까지 (0) | 2025.04.11 |