본문 바로가기
  • 프론트엔드 개발자 세오세오 | Frontend dev Seo
Learn to Code

[React] 커스텀훅(Custom Hook)

by CEOSEO 2023. 8. 16.
728x90
반응형

Custom hook이란?

React의 커스텀 훅(custom hook)은 리액트의 함수형 컴포넌트에서 상태 또는 사이드 이펙트가 있는 로직을 재사용하기 위해 캡슐화할 수 있는 특정 네이밍 규칙을 따르는 함수이다.

 

커스텀훅을 사용하면 복잡한 로직을 재사용가능한 함수로 만들어버릴 수 있는데, 이렇게 할 경우 코드가 깰끔해지고 컴포넌트 내 관심사 분리를 유지하기 쉬워진다.

 

 

 

일반 함수 vs. 커스텀훅

커스텀훅 또한 함수라고 했는데, 그렇다면 일반 함수와 커스텀 훅의 차이는 무엇일까?

 

1. 네이밍 규칙

커스텀훅들은 "use"라는 이름으로 시작해야 한다(예: useFetchData). 이를 통해 리액트가 이 친구가 커스텀훅이라는걸 알 수 있게 되고, 리액트 내부에서 진행되는 특정 최적화 작업의 대상이 될 수 있다.

 

2. 재사용성

커스텀훅은 컴포넌트간 존재할 수 있는 복잡한 로직을 캡슐화하여 재사용하는 방법이다. 이를 통해 코드 재사용성을 올리고 유지보수를 용이하게 할 수 있다.

 

3. 관심사 분리

커스텀훅은 상태가 있거나 사이드 이펙트가 있는 로직을 컴포넌트의 랜더링 로직과 분리할 수 있게 해준다.

 

 

4. 상태 분리 

커스텀 훅을 사용하는 사용하는 각 컴포넌트는 각자 'isolated'된 상태를 갖게 된다. 같은 커스텀훅을 여러 컴포넌트에서 사용하는 경우, 한 컴포넌트 내에서 사용하는 요 커스텀훅의 상태는 같은 커스텀훅을 사용하는 다른 컴포넌트의 상태와 겹치지 않는다.

 

 

5. 훅 조합

커스텀훅은 더 복잡한 행동을 만들기 위해 서로 함께 뭉칠 수 있다. 이를 통해 이미 만들어진 로직 위에 새로운 기능을 추가하는 것이 가능해진다.

 

 

 

 

Custom hook을 사용했을 때 vs. 안썼을 때

데이터를 받아오는 fetching logic은 여러 컴포넌트에서 사용 가능한 친구이기 때문에 커스텀훅으로 만들면 재사용성에 이점을 얻을 수 있는 기능이다. 만약이 이와 같이 데이터를 받아오는 로직을 날 것 그대로 컴포넌트에 작성하게 된다면 아래와 같이 될 것이다:

 

import React, { useState, useEffect } from 'react';

function AppWithoutCustomHook() {
  const [movies, setMovies] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('https://api.example.com/movies')
      .then(response => response.json())
      .then(data => {
        setMovies(data);
        setLoading(false);
      })
      .catch(error => console.error('에러가 발생해부렀어유:', error));
  }, []);

  return (
    <div>
      <h2>Movies</h2>
      {loading ? (
        <p>Loading...</p>
      ) : (
        <ul>
          {movies.map((movie, index) => (
            <li key={index}>
              <strong>{movie.title}</strong> - Rating: {movie.rating}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

export default AppWithoutCustomHook;

 

 

그러나, 위 예시 같은 경우엔 데이터를 가져오는 기능과 컴포넌트를 랜더링하는 기능이 한 컴포넌트에 복잡하게 얽히면서 관심사 분리가 명확히 되지 않는다. 뿐만 아니라, 동일한 데이터 fetching 기능을 다른 컴포넌트에서 사용하려면 동일한 코드를 그 컴포넌트에 또 써야된다는 문제가 발생하게 된다. 커스텀훅은 바로 이런 경우에 사용할 수 있는 수단이다.

 

위와 같이 작성하지 않고 fetching 기능을 별도로 쏙 뽑아내서 아래와 같이 만들 수 있다:

 

import { useState, useEffect } from 'react';

function useFetchData(url) {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        setData(data);
        setLoading(false);
      })
      .catch(error => console.error('에러가 발생해부렀어유:', error));
  }, [url]);

  return { data, loading };
}

export default useFetchData;

 

 

이렇게 쏙 뽑아내서 별도로 만든 커스텀훅을 아래와 같이 사용하면, 관심사 분리가 명확하면서도, 데이터 fetching 커스텀훅을 다른 곳에서도 재사용할 수 있게 된다:

 

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

function AppWithCustomHook() {
  const movies = useFetchData('https://api.example.com/movies');

  return (
    <div>
      <h2>Movies</h2>
      {movies.loading ? (
        <p>Loading...</p>
      ) : (
        <ul>
          {movies.data.map((movie, index) => (
            <li key={index}>
              <strong>{movie.title}</strong> - Rating: {movie.rating}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

export default AppWithCustomHook;

 

 

 

728x90
반응형

댓글