복잡한 비동기 통신이나 상태 관리 로직을 하나의 함수(Hook)로 묶어 여러 컴포넌트에서 재사용할 수 있게 만드는 고급 기법임
리액트의 내장 훅(useState, useEffect 등)을 조합하여 나만의 도구를 만드는 과정이다.
커스텀 훅을 만들 때는 리액트가 이를 일반 함수와 구분할 수 있도록 약속된 형식을 지켜야 한다.
❖ 작성 가이드:
use 접두사: 반드시 함수 이름은 use로 시작해야 함 (예: useFetch, useInput)커스텀 훅은 컴포넌트를 가볍게 만들고, 코드의 중복을 획기적으로 줄여주는 "로직 주머니"와 같다.
데이터를 가져오는 공통 로직을 useFetch.js 파일로 분리한 모습이다.
import { useEffect, useState } from 'react';
export function useFetch(fetchFn, initialValue) {
const [isFetching, setIsFetching] = useState(false);
const [error, setError] = useState();
const [fetchedData, setFetchedData] = useState(initialValue);
useEffect(() => {
async function fetchData() {
setIsFetching(true);
try {
const data = await fetchFn();
setFetchedData(data);
} catch (error) {
setError({ message: error.message || '데이터를 불러오지 못했습니다.' });
}
setIsFetching(false);
}
fetchData();
}, [fetchFn]);
// 컴포넌트에서 필요한 값들을 객체 형태로 반환
return { isFetching, fetchedData, setFetchedData, error };
}
- 매개변수 전달: 컴포넌트에서 실행할 비동기 함수(
fetchFn)와 초기값(initialValue)을 훅에 넘겨줌- 내부 상태 관리: 훅 내부에서 로딩, 에러, 데이터 상태를 독립적으로 관리함
- 자동 실행:
useEffect를 통해 컴포넌트가 마운트될 때 데이터를 자동으로 가져옴- UI 연결: 컴포넌트는 훅이 리턴한 값들을 구조 분해 할당으로 받아 화면을 그리는 데만 집중함
컴포넌트 파일 안에 수십 줄의 useEffect와 useState가 섞여 있으면 가독성이 떨어진다.
❖ 최적화 효과:
useFetch)만 봐도 이 로직이 무엇을 하는지 한눈에 파악할 수 있음