본문 바로가기

리액트

✅ [18편] 리액트 커스텀 훅(Custom Hook) 완벽 가이드: 반복 로직을 효율적으로 관리하는 실무 전략

✅ 리액트 커스텀 훅(Custom Hook) 완벽 가이드: 반복 로직을 효율적으로 관리하는 실무 전략

리액트를 사용하다 보면 컴포넌트 내부에서 동일하거나 유사한 로직을 여러 번 반복하는 상황이 흔히 발생합니다. 예를 들어 다음과 같은 기능들입니다.
입력값 상태 관리
API 요청 처리
스크롤 감지
브라우저 정보 확인
타이머 제어
이런 반복되는 로직을 컴포넌트마다 직접 작성하면 코드 중복이 증가하고 유지보수가 매우 어려워집니다.
리액트에서는 이러한 문제를 해결하기 위해 커스텀 훅(Custom Hook) 개념을 제공합니다.
커스텀 훅은 리액트의 핵심 개념 중 하나로, 컴포넌트 간에서 공통으로 필요한 로직을 재사용 가능하게 만드는 확장 기능입니다.
이번 글에서는 커스텀 훅의 개념, 사용 원리, 실무 설계 패턴, 그리고 고급 활용까지 깊이 있게 다뤄보겠습니다.


🟦 1. 커스텀 훅이란 무엇인가?

커스텀 훅(Custom Hook)은 리액트의 hook 기능을 활용해 사용자가 직접 만드는 훅입니다.
기본 훅(useState, useEffect 등)을 조합하여 새로운 기능을 추출한 일종의 “재사용 가능한 함수를 만드는 기술”이라고 할 수 있습니다.
✔ 커스텀 훅 특징
이름이 반드시 use로 시작해야 한다
내부에서 다른 훅 사용 가능
UI가 없는 ‘로직 재사용’ 전용 기능
컴포넌트마다 독립된 상태 인스턴스 생성
코드 중복을 줄이고 유지보수성을 높임
예를 들어 다음 같은 입력 관리 로직을 여러 컴포넌트에서 사용해야 한다면?
const [value, setValue] = useState("");
const onChange = (e) => setValue(e.target.value);
커스텀 훅으로 만들면 다음처럼 간결하게 재사용할 수 있습니다.


🟦 2. 가장 기본적인 커스텀 훅 예시: useInput


반복적인 입력값 관리를 추출해보겠습니다.


🔷 커스텀 훅 정의


import { useState } from "react";
export function useInput(initialValue = "") {
const [value, setValue] = useState(initialValue);
const onChange = (e) => {
setValue(e.target.value);
};
return { value, onChange, setValue };
}


🔷 사용 예시


function LoginForm() {
const email = useInput("");
const password = useInput("");
return (
<>
<input {...email} placeholder="이메일" />
<input {...password} type="password" placeholder="비밀번호" />
</>
);
}
입력 로직을 재사용할 수 있어 컴포넌트가 매우 깔끔해지며 유지보수도 쉬워집니다.


🟦 3. 커스텀 훅이 필요한 이유: 실무 관점에서의 가치


커스텀 훅의 가치는 단순히 “코드 줄이기”에 있지 않습니다.
진짜 중요한 이유는 다음 3가지를 해결하기 때문입니다.
✔ 1) 코드 중복 제거
여러 컴포넌트에서 동일한 로직이 반복되면 유지보수 비용이 폭발적으로 증가합니다.
예를 들어 API 호출 후 다음 절차가 계속 반복됩니다.
로딩 상태 관리
에러 처리
성공 상태 업데이트
이 로직을 커스텀 훅으로 만들면 한 곳에서 관리할 수 있습니다.
✔ 2) 컴포넌트가 가벼워지고 역할 분리가 명확해짐
컴포넌트는 원래 “UI만 담당하는 구조”가 이상적입니다.
하지만 복잡한 로직이 섞이면 UI를 이해하기 어려워지고 버그가 발생하기 쉽습니다.
커스텀 훅을 사용하면
UI → 컴포넌트,
로직 → 커스텀 훅으로
역할 분리가 자연스럽게 일어납니다.
✔ 3) 테스트와 유지보수가 훨씬 쉬워짐
로직이 커스텀 훅으로 분리되면 로직 단독 테스트도 가능해지고, 로직이 한곳에 모여 있으므로 수정할 때도 편합니다.


🟦 4. 실무에서 가장 많이 쓰이는 커스텀 훅 종류


실제 개발자들이 자주 만드는 커스텀 훅 유형은 다음과 같습니다.

🔹 1) 입력값 관리 → useInput
가장 기본적이고 재사용성이 높습니다.
🔹 2) API 요청 관리 → useFetch or useApi
로딩, 에러, 성공 상태를 관리하므로 거의 모든 프로젝트에서 사용합니다.
예:
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
const load = async () => {
setLoading(true);
try {
const res = await fetch(url);
setData(await res.json());
} catch (e) {
setError(e);
} finally {
setLoading(false);
}
};
load();
}, [url]);
return { data, loading, error };
}
🔹 3) 디바운스/스로틀 → useDebounce / useThrottle
검색창 최적화, 스크롤 이벤트 성능 개선용
🔹 4) 윈도우 이벤트 감지 → useScroll, useResize
브라우저 전역 이벤트 재사용
🔹 5) 토글 상태 관리 → useToggle
ON/OFF 플래그를 단순히 관리할 때 아주 유용합니다.
function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = () => setValue((prev) => !prev);
return [value, toggle];
}


🟦 5. 커스텀 훅 설계 원칙 5가지


커스텀 훅을 제대로 만들기 위해서는 설계가 매우 중요합니다.
아래 원칙을 지키면 재사용성이 높고 버그가 적은 훅을 만들 수 있습니다.
✔ 1) ‘하나의 역할’만 수행하게 하기
하나의 훅이 너무 많은 기능을 포함하면 다시 분리하기 어려워집니다.
✔ 2) 이름은 반드시 use로 시작
리액트가 내부적으로 훅을 인식하기 위한 규칙입니다.
✔ 3) 외부 노출 API 설계는 최소한으로
필요 없는 함수나 값을 반환하지 않아야 재사용성이 높아집니다.
✔ 4) 커스텀 훅 내부에서 상태를 직접 조작하지 말고 반환값으로 제어
예: setState를 반환해 외부에서 제어하도록 설계
✔ 5) 부수효과(useEffect)는 최소화
훅은 기본적으로 상태 로직을 담당해야 하고, 필요할 때만 useEffect를 사용해야 합니다.


🟦 6. 커스텀 훅을 사용할 때 자주 발생하는 실수


커스텀 훅을 처음 사용할 때 흔히 생기는 문제들을 정리해보겠습니다.
❌ 실수 1: 훅 내부에서 조건문으로 훅 사용
훅은 항상 컴포넌트 최상단에서 호출되어야 합니다.
if (조건) {
useState() // ❌ 사용 불가
}
❌ 실수 2: 훅의 반환값을 구조적으로 설계하지 않음
너무 많은 데이터 반환 → 재사용 어려움
❌ 실수 3: 훅 내부에 useEffect 의존성 누락
API 요청 훅에서 종종 발생하는 문제
❌ 실수 4: 재사용성을 고려하지 않고 작성
특정 컴포넌트에 종속된 훅은 커스텀 훅의 의미가 없음

 

🟦 7. 커스텀 훅을 사용해야 하는 실무 사례


아래 상황에서 커스텀 훅을 사용하면 프로젝트 품질이 크게 향상됩니다.
✔ 1) 동일한 입력창 로직을 여러 컴포넌트가 사용할 때
→ useInput 생성
✔ 2) API 요청이 여러 페이지에서 반복될 때
→ useFetch or useApi 구축
✔ 3) 스크롤 위치에 따라 UI가 바뀌는 경우
→ useScroll
✔ 4) 복잡한 폼 검증 로직
→ useFormValidator 형태로 분리
✔ 5) 인터랙션(모달, 드롭다운 등) 제어
→ useToggle
→ useBoolean
→ useDisclosure 패턴 활용
이처럼 “반복되는 패턴”을 발견하는 순간 커스텀 훅을 만들 기회입니다.


🟦 결론: 커스텀 훅은 리액트 개발을 ‘단순하면서도 강력하게’ 만든다


커스텀 훅을 잘 활용하면 리액트 프로젝트의 유지보수성과 설계 품질이 눈에 띄게 상승합니다.
단순히 코드를 줄여주는 것을 넘어 로직을 정돈하고, UI와 로직을 분리하며, 프로젝트 구조를 명확하게 만든다는 점에서 필수적인 기술입니다.
잘 만들어진 커스텀 훅 하나는 프로젝트 전체에서 “공통 로직 관리의 중심”이 되어 개발 효율을 크게 높입니다.
리액트 실력 향상을 위해서도 커스텀 훅은 반드시 익히고 활용해야 할 핵심 기술입니다.