본문 바로가기
React

[React] 커스텀 훅 만들기

by goblin- 2024. 9. 15.

커스텀 훅(Custom Hook) 만들기

 

**커스텀 훅(Custom Hook)**은 리액트의 기본 훅들을 조합하여 재사용 가능한 상태 로직을 만드는 방식입니다. 커스텀 훅을 사용하면 컴포넌트에서 반복되는 로직을 분리하여 중복을 줄이고, 코드의 재사용성을 높일 수 있습니다. 커스텀 훅은 기본적으로 일반 자바스크립트 함수처럼 동작하며, 이름이 반드시 **use**로 시작해야 합니다.

 

1. 커스텀 훅의 필요성

 

리액트에서 여러 컴포넌트가 동일한 상태 관리나 로직을 필요로 할 때, 각 컴포넌트마다 해당 로직을 반복적으로 작성하면 중복된 코드가 발생할 수 있습니다. 이럴 때 커스텀 훅을 사용하면 로직을 추상화하고 재사용할 수 있습니다.

 

예를 들어, 여러 컴포넌트에서 API 호출이나 이벤트 리스너 설정 같은 로직이 중복된다면, 이를 커스텀 훅으로 분리하여 관리할 수 있습니다. 커스텀 훅은 기본 훅들처럼 상태 관리, 사이드 이펙트 처리, 값 추적 등을 수행할 수 있습니다.

 

2. 커스텀 훅의 기본 구조

 

커스텀 훅은 일반 함수처럼 정의되지만, 이름이 반드시 **use**로 시작해야 합니다. 이 함수 내부에서 useState, useEffect, useRef 등 리액트의 기본 훅들을 조합하여 로직을 작성합니다.

function useCustomHook() {
  // 훅 내부에서 상태나 로직을 관리
  const [state, setState] = useState(initialState);

  // 예시로 사이드 이펙트 처리
  useEffect(() => {
    // 특정 동작을 수행
  }, []);

  // 훅에서 값을 반환 (상태나 함수 등을 반환 가능)
  return [state, setState];
}

 

3. 커스텀 훅 예시 1: 윈도우 크기 추적

 

아래 예시는 윈도우 크기를 추적하는 커스텀 훅을 만드는 예시입니다. 여러 컴포넌트에서 동일한 윈도우 크기 추적 로직이 필요할 경우, 이 훅을 통해 코드를 재사용할 수 있습니다.

import { useState, useEffect } from 'react';

// 윈도우 크기 추적 커스텀 훅
function useWindowSize() {
  const [windowSize, setWindowSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  useEffect(() => {
    // 윈도우 크기가 변경될 때마다 상태를 업데이트하는 함수
    const handleResize = () => {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    };

    // 윈도우 리사이즈 이벤트 리스너 등록
    window.addEventListener('resize', handleResize);

    // 컴포넌트가 언마운트될 때 이벤트 리스너 제거
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // 빈 배열을 사용하여 컴포넌트가 처음 렌더링될 때 한 번 실행

  return windowSize; // 현재 윈도우 크기 반환
}

export default useWindowSize;

설명:

 

**useWindowSize**는 윈도우의 **가로(width)**와 세로(height) 크기를 추적하는 커스텀 훅입니다.

컴포넌트가 처음 렌더링될 때 resize 이벤트 리스너를 등록하고, 컴포넌트가 언마운트될 때 이벤트 리스너를 정리(clean-up)합니다.

windowSize 객체는 현재의 윈도우 크기를 저장하며, 이 값은 컴포넌트에서 사용할 수 있습니다.

 

이 커스텀 훅은 여러 컴포넌트에서 사용할 수 있으며, 각 컴포넌트는 중복 없이 동일한 로직을 활용할 수 있습니다.

 

커스텀 훅 사용 예시:

import React from 'react';
import useWindowSize from './useWindowSize';

function WindowSizeComponent() {
  const { width, height } = useWindowSize();

  return (
    <div>
      <p>Window width: {width}</p>
      <p>Window height: {height}</p>
    </div>
  );
}

export default WindowSizeComponent;

 

4. 커스텀 훅 예시 2: API 데이터 가져오기

 

아래 예시는 API 호출 로직을 커스텀 훅으로 분리하는 예시입니다. 이 훅은 다양한 컴포넌트에서 API 데이터를 가져오는 공통 로직을 재사용할 수 있게 합니다.

import { useState, useEffect } from 'react';

// API 데이터를 가져오는 커스텀 훅
function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const result = await response.json();
        setData(result); // 데이터 저장
      } catch (error) {
        setError(error); // 오류 처리
      } finally {
        setLoading(false); // 로딩 상태 종료
      }
    };

    fetchData();
  }, [url]); // url이 변경될 때마다 다시 실행

  return { data, loading, error }; // 상태 반환
}

export default useFetch;

 

설명:

 

useFetch 훅은 주어진 url에서 API 데이터를 가져오는 로직을 처리합니다.

**로딩 상태(loading)**와 **에러 상태(error)**도 관리하며, 데이터를 받아오면 컴포넌트에서 사용할 수 있습니다.

url이 바뀔 때마다 useEffect가 다시 실행되므로, 동적으로 API를 호출할 수 있습니다.

 

커스텀 훅 사용 예시:

import React from 'react';
import useFetch from './useFetch';

function DataFetchingComponent() {
  const { data, loading, error } = useFetch('https://api.example.com/data');

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error occurred: {error.message}</p>;

  return <div>Data: {JSON.stringify(data)}</div>;
}

export default DataFetchingComponent;

설명:

 

useFetch 훅을 사용하여 데이터를 가져오고, 컴포넌트 내에서 data, loading, error를 처리합니다.

이 훅은 다른 API 호출에서도 재사용 가능하므로 코드 중복을 줄이고 유지보수성을 높일 수 있습니다.

 

5. 커스텀 훅의 장점

 

코드 재사용성: 커스텀 훅은 로직을 캡슐화하여 다양한 컴포넌트에서 재사용할 수 있습니다. 여러 컴포넌트에서 동일한 상태 관리나 로직이 필요할 때, 중복된 코드를 줄일 수 있습니다.

분리된 관심사: 커스텀 훅을 사용하면 컴포넌트의 UI와 비즈니스 로직을 분리할 수 있습니다. 훅은 로직에만 집중하고, 컴포넌트는 UI 렌더링에만 집중할 수 있어 코드 가독성이 높아집니다.

독립적인 테스트 가능성: 커스텀 훅은 독립적으로 테스트할 수 있습니다. 훅이 상태 관리나 API 호출 등의 로직을 처리하므로, 각 훅을 별도로 테스트할 수 있어 코드 품질을 유지할 수 있습니다.

 

6. 커스텀 훅 작성 시 유의점

 

1. 훅의 이름 규칙: 커스텀 훅의 이름은 반드시 **use**로 시작해야 합니다. 이를 통해 리액트는 해당 함수가 훅이라는 것을 인식하고, 컴포넌트 렌더링과 훅의 호출 순서를 관리합니다.

2. 훅 내부에서 다른 훅 호출: 커스텀 훅 내부에서는 다른 훅(useState, useEffect, useRef 등)을 자유롭게 호출할 수 있습니다. 훅의 가장 큰 장점 중 하나는 기본 훅을 조합하여 더 복잡한 로직을 처리할 수 있다는 것입니다.

3. 훅의 규칙 준수: 커스텀 훅은 기본 훅과 동일한 훅의 규칙을 따라야 합니다. 예를 들어, 훅은 컴포넌트 최상단에서 호출되어

'React' 카테고리의 다른 글

[React] VDOM의 원리  (1) 2024.09.21
[React] 직접적인 Dom조작은 피해라  (1) 2024.09.15
[React] useRef 와 useEffect의 차이점  (0) 2024.09.14
[React] useRef 훅 사용법  (1) 2024.09.13
[React] useEffect 훅, 의존성 배열  (0) 2024.09.13