[React] Custom Hook

✨ 강은비·2022λ…„ 1μ›” 30일
0

React

λͺ©λ‘ 보기
30/36
post-thumbnail

πŸ’‘ μ»€μŠ€ν…€ 훅을 μ΄μš©ν•΄ μ»΄ν¬λ„ŒνŠΈ λ‘œμ§μ„ ν•¨μˆ˜λ‘œ λ§Œλ“€μ–΄ μž¬μ‚¬μš©ν•  수 μžˆλ‹€.

πŸ“Œ μ˜ˆμ‹œ

// FriendStatus

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

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

✨ μ»€μŠ€ν…€ 훅을 λ§Œλ“€μ–΄ 쀑볡 둜직 μ΅œμ†Œν™”ν•˜κΈ°

  • μ»€μŠ€ν…€ 훅은 이름이 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;
}

✨ μ»€μŠ€ν…€ ν›… μ‚¬μš©ν•˜κΈ°

// FriendStatus

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

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

function FriendListItem(props) {
  const isOnline = useFriendState(props.friend.id);
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}
  • 같은 Hook을 μ‚¬μš©ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλŠ” stateλ₯Ό κ³΅μœ ν•˜μ§€ μ•ŠλŠ”λ‹€.
  • 각각의 Hook에 λŒ€ν•œ ν˜ΈμΆœμ€ μ„œλ‘œ λ…λ¦½λœ stateλ₯Ό λ°›λŠ”λ‹€.
  • React κ΄€μ μ—μ„œ λ‹¨μˆœνžˆ 각 μ»΄ν¬λ„ŒνŠΈμ—μ„œ useState와 useEffectλ₯Ό ν˜ΈμΆœν•œ 것이기 λ•Œλ¬Έμ— 각 μ»΄ν¬λ„ŒνŠΈμ˜ state와 effectλŠ” 독립적이닀.

✨ Hookμ—μ„œ Hook으둜 정보 μ „λ‹¬ν•˜κΈ°

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>
    </>
  );
}
  • μ§€κΈˆ μ„ νƒλ˜μ–΄ μžˆλŠ” 친ꡬ의 온라인 μƒνƒœ μ—¬λΆ€λ₯Ό μ•Œ 수 μžˆλ‹€.
  • λ‹€λ₯Έ 친ꡬλ₯Ό μ„ νƒν•˜κ³  recipientIDλ₯Ό μ—…λ°μ΄νŠΈν•˜λ©΄ useFriendStatus Hook은 이미 μ„ νƒλ˜μ–΄ μžˆλŠ” 친ꡬ의 ꡬ독을 ν•΄μ§€ν•˜κ³  μƒˆλ‘œ μ„ νƒλœ 친ꡬ의 μƒνƒœλ₯Ό ꡬ독할 것이닀.

μ°Έκ³ : React κ³΅μ‹λ¬Έμ„œ

0개의 λŒ“κΈ€