본문 바로가기
Web/React.js

[STUDY] 커스텀 Hooks

by 폴우정킴 2021. 3. 27.
  • 자신만의 Hook를 만들면 컴포넌트 로직을 함수로 뽑아 재사용 할 수 있다.
// 채팅 애플리케이션에서 친구가 온라인인지 아닌지에 대한
// 메시지를 표시하는 컴포넌트 

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

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
  • 리액트에서는 상태 관련 로직을 컴포넌트에서 공유하는 두 가지의 전통적인 방법이 있다.
    1. render props
    2. 고차 컴포넌트
  • Hook를 사용하여 트리에 컴포넌트를 더하지 않고 위 문제를 해결 할 수 있다.

사용자 정의 Hook 추출하기

  • 두 개의 자바스크립트 함수에서 같은 로직을 공유하고자 할 때는 또 다른 함수로 분리한다. ( 컴포넌트 Hook 또한 함수이다 ! )
  • Hook 규칙이 잘 적용되어 있는 Hook임을 명확히 하기 위해 사용자 정의 hook의 이름을 use로 시작하자
// 사용자 정의 Hook, 컴포넌트의 로직과 같다. 

import { useState, useEffect } from 'react';

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}
  • 컴포넌트 처럼 Hook들은 사용자 Hook의 위로 놓여야 하며 사용자 정의 Hook는 조건부 함수가 아니어야 한다.
  • 컴포넌트와는 다르게 사용자 정의 Hook는 무엇을 인수로 받아야 하며 무엇을 반환하는지 사용자가 결정 할 수 있다.
function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  // ...

  return isOnline;
}
  • useFriendStatus Hook의 목표는 친구의 상태를 구독하기 위함이며 이를 위해 friendID를 이수로 받고 온라인 상태 여부를 반환한다.

사용자 정의 Hook 이용하기

  • FriendStatus 와 FriendListItem 이라는 두 컴포넌트의 중복되어 있는 로직을 제거 하는 것이 최종 목표다. (두 컴포넌트 모두 친구의 온라인 상태 여부를 알아야 한다)
function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}
  • 위에서 두 컴포넌트에서 useFriendStatus Hook를 사용하고 있다.

커스텀 Hook의 이름이 use로 시작하는 이유

  • 이 관습을 따르지 않으면 특정한 함수가 그 안에서 Hook를 호출하는지를 알 수 없기 때문에 Hook규칙의 위반 여부를 자동으로 체크할 수 없다.

같은 Hook를 사용하는 두개의 컴포넌트의 state 공유 여부

  • 커스텀 Hook는 상태 관련 로직(구독을 설정하고 변수값을 기억하는 정도)를 재사용한다.
  • 그 안의 state와 effect는 완전히 독립적이다.

사용자 정의 Hook는 어떻게 독립된 state를 얻는가

  • useFriendStatus를 직접적으로 호출하기 때문에 react의 관점에서는 useState와 useEffect를 호출한것과 같다.
  • Hook는 하나의 컴포넌트 안에서 useState와 useEffect를 여러번 호출할 수 있고 이들은 모두 독립적이다.

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

Suspense를 사용하자  (0) 2021.12.14
[STUDY] Hook의 규칙  (0) 2021.03.23
[STUDY] Effect Hook 사용하기  (0) 2021.03.22
[STUDY] State Hook 사용하기  (0) 2021.03.21
[STUDY] Hook 개요  (0) 2021.03.19

댓글