본문 바로가기
Front-End/React

[React Hook] 5. 자신만의 Hook 만들기 (완)

by hongdor 2021. 2. 23.
728x90

출처 공식 문서 : 자신만의 Hook 만들기 – React (reactjs.org) 

 

 

1. 자신만의 Hook을 통해 컴포넌트 로직을 함수로 뽑아낼 수 있습니다.

2. 예시 코드에 앞서 부연 설명

> 채팅 어플리케이션에서 친구가 온라인 상태인지 아닌지 표시하는 2개의 컴포넌트에서
  공통 Hook들을 뽑아낸다.
  하지만 여기서도 마찬가지로,조건문 혹은 반복문안에 들어가지 않고 최상위에 있어야 한다.
  그리고 구분하기 쉽게 use로 시작하는 함수이름을 사용한다.

 

예시)

(1)

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';
}

 

(2)

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

function FriendListItem(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);
    };
  });

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

 

 

(3) (1)과 (2)에서 공통된 로직을 useFriendStatus 함수로 뽑는다

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;
}

 

(4) (1)을 수정

function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

 

(5) (2)를 수정 (끝)

function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

 

 

3. 위 (1)과 (2) 두개의 컴포넌트는 useFriendStatus 함수를 공통으로 사용하지만

state를 공유하지 않는다.

 

 

4. 팁 : Hook에서 Hook으로 정보 전달하기


예시)

const friendList = [
  { id: 1, name: 'Phoebe' },
  { id: 2, name: 'Rachel' },
  { id: 3, name: 'Ross' },
];

function ChatRecipientPicker() {
  const [recipientID, setRecipientID] = useState(1);
  const isRecipientOnline = useFriendStatus(recipientID);

  return (
    <>
      <Circle color={isRecipientOnline ? 'green' : 'red'} />
      <select
        value={recipientID}
        onChange={e => setRecipientID(Number(e.target.value))}
      >
        {friendList.map(friend => (
          <option key={friend.id} value={friend.id}>
            {friend.name}
          </option>
        ))}
      </select>
    </>
  );
}


>> 여기서 useFriendStatus(recipientID); 는 커스텀 Hook이고
   select 태그를 통해 값이 바뀔경우 recipientID 값이 변하면서 useState Hook이 호출되고 다시 렌더링 된다. 
   useFriendStatus Hook 커스텀 함수에 recipientID 최신값을 돌려주면서 useFriendStatus 속 useState 와 useEffect 들이 실행된다.

 

 

5. 추가로 읽어 볼것

 

아래는 공식문서들에 있으나 생략한 것들이므로 꼭 클릭해봐야 합니다.

 

Hook 개요

Hook 개요 – React (reactjs.org)

 

Hook API 참고서

Hooks API Reference – React (reactjs.org)

 

Hook 자주 묻는 질문

Hook 자주 묻는 질문 – React (reactjs.org)

728x90

'Front-End > React' 카테고리의 다른 글

[React Hook] 4. Hook 규칙  (0) 2021.02.23
[React Hook] 3. Effect Hook  (0) 2021.02.23
[React Hook] 2. State Hook  (0) 2021.02.22
[React Hook] 1. Hook 소개  (0) 2021.02.22
[react-redux] 5. 요약 (완)  (0) 2021.02.17

댓글