Custom Hook 만들기

2025. 6. 25. 17:56·기술/React.js

커스텀 훅(Custom Hook)이란?

리액트의 내장 훅(useState, useEffect, 등)을 활용해

자주 쓰이는 로직을 함수처럼 재사용할 수 있도록 만든 사용자 정의 훅을 말합니다.

// 이름은 반드시 use로 시작해야 함
function useSomething() {
  // 내부에서 다른 훅 사용 가능
  return ...;
}

 

왜 커스텀 훅을 사용할까?

1. 로직의 재사용

  • 같은 useState, onChange 로직을 매번 반복해서 작성하는 건 비효율적 입니다.
  • 훅으로 빼서 함수처럼 가져다 쓰면 됩니다.

2. 컴포넌트 간 중복 제거

  • 예: 폼 입력 관리, 로딩/에러 처리, fetch 요청 등

3. UI가 아닌 로직만 다룬다 (로직 추출 전용)

  • UI 컴포넌트와 로직이 분리되어 코드 가독성/테스트성 향상됩니다.

4. 각 컴포넌트마다 상태는 독립적으로 관리됨

  • 커스텀 훅을 여러 곳에서 써도, 각자 state를 가집니다. (전역 상태 아님!)

대표예시

// src/hooks/useInput.js
import { useState } from "react";

function useInput(initialValue = "") {
  const [value, setValue] = useState(initialValue);

  const handleChange = (e) => {
    setValue(e.target.value);
  };

  return [value, handleChange];
}

export default useInput;

중복되는 코드들을 내장 훅을 사용해서 커스텀 훅으로 만든 후 리턴값으로 반환

import useInput from "../hooks/useInput";

function LoginForm() {
  const [email, onChangeEmail] = useInput();
  const [password, onChangePassword] = useInput();

  return (
    <form>
      <input value={email} onChange={onChangeEmail} />
      <input value={password} onChange={onChangePassword} />
    </form>
  );
}

 

커스텀 훅으로 만들어 보면 좋은 상황들

  • ✅ 인풋 상태 관리 (useInput)
  • ✅ 토글 열고 닫기 (useToggle)
  • ✅ 타이머 (useInterval)
  • ✅ 브라우저 사이즈 감지 (useWindowSize)
  • ✅ 스크롤 위치 추적 (useScroll)
  • ✅ API 호출 (useFetch)
  • ✅ 외부 이벤트 감지 (useOutsideClick)

 

커스텀 훅 가이드

1. 우선 반복되는 로직이 있는지 살펴봅니다.

이걸 매번 컴포넌트에서 다시 작성할 필요 있을까?" 를 계속 고민하면 좋습니다.

 

예를 들어 폼을 작성할 때 매번 이런 코드가 반복된다고 해보겠습니다.

function LoginForm() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  const onChangeEmail = (e) => setEmail(e.target.value);
  const onChangePassword = (e) => setPassword(e.target.value);

  return (
    <form>
      <input value={email} onChange={onChangeEmail} />
      <input value={password} onChange={onChangePassword} />
    </form>
  );
}

 

2. 재사용 단위로 추출하기

그 로직의 입출력을 정리해보면  어떤 값을 받아서 어떤 값을 반환해야 컴포넌트가 사용하기 편할지 감을 잡을 수 있습니다.

function useInput(initialValue = "") {
  const [value, setValue] = useState(initialValue);
  const handleChange = (e) => setValue(e.target.value);
  return [value, handleChange];
}

 

3. 훅으로 분리하기

  • 훅은 반드시 컴포넌트 최상단에서 호출
  • 호출 순서는 항상 동일해야 함
  • 훅 이름은 반드시 use로 시작
import { useState } from "react";

function useInput(initialValue = "") {
  const [value, setValue] = useState(initialValue);
  
  const handleChange = (e) => {
    setValue(e.target.value);
  };

  return [value, handleChange];
}

export default useInput;

 

4. 실제 코드에서 사용해보기

훅을 분리해서 훨씬 가독성있고 중복코드 없이 사용할 수 있습니다.

import useInput from "./hooks/useInput";

function LoginForm() {
  const [email, onChangeEmail] = useInput();
  const [password, onChangePassword] = useInput();

  return (
    <form>
      <input value={email} onChange={onChangeEmail} />
      <input value={password} onChange={onChangePassword} />
    </form>
  );
}

 

*요약

반복되는 상태 관리 → 입출력 정리 → 훅으로 분리 → 내부에서 훅 조합 → 독립적으로 사용하기
저작자표시 비영리 변경금지 (새창열림)

'기술 > React.js' 카테고리의 다른 글

React의 렌더링과 리렌더링 흐름  (2) 2025.06.22
React가 빠른 이유: Virtual DOM, Diffing, Reconciliation, Batch Update 이해하기  (0) 2025.06.18
리액트의 특징에 대해 알아보자  (2) 2025.06.18
[문서] 리액트 공식문서 톱아보기: 컴포넌트를 순수하게 유지하자  (1) 2025.05.06
[문서] 리액트 공식문서 톱아보기: 컴포넌트 import 및 export  (1) 2024.11.16
'기술/React.js' 카테고리의 다른 글
  • React의 렌더링과 리렌더링 흐름
  • React가 빠른 이유: Virtual DOM, Diffing, Reconciliation, Batch Update 이해하기
  • 리액트의 특징에 대해 알아보자
  • [문서] 리액트 공식문서 톱아보기: 컴포넌트를 순수하게 유지하자
빔네모
빔네모
console.log("빔네모")
  • 빔네모
    bimnemo("개발")
    빔네모
  • 전체
    오늘
    어제
    • 기록 (164)
      • 기술 (51)
        • JavaScript (8)
        • TypeScript (9)
        • React.js (14)
        • Next.js (0)
        • 라이브러리,도구 (5)
        • HTML,CSS (4)
        • CS (5)
        • BE (4)
        • 테스트 (2)
      • 개발 (99)
        • 프로젝트 (0)
        • 트러블슈팅 (5)
        • 알고리즘(코딩테스트) (94)
      • 정보 (4)
      • 취미 (10)
        • 독서기록 (10)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
빔네모
Custom Hook 만들기
상단으로

티스토리툴바