[React] (리액트 공부하기 19) 나만의 훅 만들기

젼이·2025년 1월 13일

리액트 정복하기

목록 보기
19/36

이 부분은 커스텀 훅(Custom Hook)을 만드는 방법을 설명한다.
커스텀 훅은 React에서 자주 사용되는 반복적인 로직을 재사용하기 위해 만들어지는 사용자 정의 함수이다.


1. 커스텀 훅을 만들어야 하는 상황

예제로는 사용자 온라인/오프라인 상태를 확인하는 컴포넌트를 만들고 있다.
UserStatus라는 컴포넌트와 UserListItem이라는 컴포넌트가 같은 로직을 공유하고 있어서 이를 중복 제거하기 위해 커스텀 훅을 추출한다.


예제 코드1: 중복된 로직

function UserStatus(props) {
  const [isOnline, setIsOnline] = useState(null);
  
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    
    ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
    return () => {
      ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
    };
  });
  
  return isOnline ? "온라인" : "오프라인";

이 코드는 사용자의 온라인 상태를 구독(subscribe)하고, 변경될 때마다 상태를 업데이트한다. 만약 비슷한 로직을 가진 또 다른 컴포넌트(UserListItem)를 만든다면 중복 코드가 많아진다.





2. 커스텀 훅 추출하기

커스텀 훅: useUserStatus

function useUserStatus(userId) {
  const [isOnline, setIsOnline] = useState(null);
  
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    
    ServerAPI.subscribeUserStatus(userId, handleStatusChange);
    return () => {
      ServerAPI.unsubscribeUserStatus(userId, handleStatusChange);
    };
  }, [userId]);
  
  return isOnline;

설명:

  1. 커스텀 훅은 일반 함수처럼 보이지만, 내부에서 React 훅(useState, useEffect 등)을 사용할 수 있다.
  2. 이 훅은 userId를 받아서 그 유저의 온라인 상태를 반환한다.
  3. 상태(isOnline)와 로직(useEffect로 구독 설정)을 한곳에 모아서 재사용 가능하게 만든다.

하나씩 쪼개서 설명

  1. 커스텀 훅이란?
  • 그냥 일반적인 JavaScript 함수처럼 보이는 React 함수이다.
  • 이 함수 안에서는 useState, useEffect 같은 훅을 사용할 수 있다.
  1. 이 코드가 하는 일:
  • 특정 userId에 대한 "온라인/오프라인 상태"를 추적한다.
  • 추적한 결과(온라인 상태)를 isOnline이라는 값으로 반환한다.

코드 쪼개보기

const [isOnline, setIsOnline] = useState(null);
  • isOnline: 현재 사용자의 온라인 상태를 저장한다. (null은 아직 알 수 없다는 뜻)
  • setIsOnline: isOnline 값을 업데이트 할 수 있는 함수

useEffect(() => {
  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }
  ServerAPI.subscribeUserStatus(userId, handleStatusChange);
  return () => {
    ServerAPI.unsubscribeUserStatus(userId, handleStatusChange);
  };
}, [userId]);
  1. 컴포넌트가 처음 렌더링 되었을 때, SerberAPI.subscribeUserStatus로 서버에서 사용자의 상태를 구독(subscribe)한다.
  2. 상태가 변경되면 handleStatusChange가 호출되어 isOnline를 업데이트 한다.
  3. 컴포넌트가 사라질 때(return 부분), 서버와의 구독을 해제한다

return isOnline;

이 커스텀 훅은 "현재 사용자(userId)의 온라인 상태"를 반환한다.




3. 커스텀 훅 사용하기

새로운 컴포넌트들

이제 useUserStatus 훅을 사용하면 로직을 재사용할 수 있다.

function UserStatus(props) {
  const isOnline = useUserStatus(props.user.id);
  
  return <div>{isOnline ? "온라인" : "오프라인"}</div>;
}

function UserListItem(props) {
  const isOnline = useUserStatus(props.user.id);
  
  return (
    <li style={{ color: isOnline ? "green" : "black" }}>
      {props.user.name}
    </li>
  );
}

변화된 점:
1. useUserStatus 훅을 추출해서 isOnline 값을 가져온다.
2. 두 컴포넌트 모두 중복 코드 없이 useUserStatus를 호출하기만 하면 된다.
3. 스타일이나 상태를 다르게 렌더링하는 로직은 각각의 컴포넌트에서 따로 처리할 수 있다.


하나씩 쪼개서 설명

function UserStatus(props) {
  const isOnline = useUserStatus(props.user.id);
  
  return <div>{isOnline ? "온라인" : "오프라인"}</div>;
}
  1. useUserStatus(props.user.id)
  • 이함수는 위에서 만든 커스텀 훅을 추출한다.
  • props.user.id라는 값을 전달하면 해당 사용자의 온라인 상태를 반환한다.



4. 훅의 규칙

  • 반드시 React 함수 컴포넌트 안에서 호출해야 한다. 일반적인 자바스크립트 함수에서 호출하면 안 된다.
  • 최상위 레벨에서 호출해야 한다. 조건문, 반복문 안에서 호출하면 훅의 호출 순서가 달라져서 오류가 발생할 수 있다.
profile
신입 개발자 임니당 : > (2025.02.05~)

0개의 댓글