[React] Custom Hooks

μœ μ•„ν˜„Β·2023λ…„ 1μ›” 25일
0

React

λͺ©λ‘ 보기
21/28
post-thumbnail

πŸ“Œ Custom Hooks

  • κ°œλ°œμžκ°€ 슀슀둜 μ»€μŠ€ν…€ν•œ 훅을 의미
  • 이λ₯Ό μ΄μš©ν•΄ λ°˜λ³΅λ˜λŠ” λ‘œμ§μ„ ν•¨μˆ˜λ‘œ 뽑아내어 μž¬μ‚¬μš©ν•  수 μžˆλ‹€.

μ—¬λŸ¬ url을 fetchν•  λ•Œ, μ—¬λŸ¬ input에 μ˜ν•œ μƒνƒœ λ³€κ²½ λ“± λ°˜λ³΅λ˜λŠ” λ‘œμ§μ„ λ™μΌν•œ ν•¨μˆ˜μ—μ„œ μž‘λ™ν•˜κ²Œ ν•˜κ³  싢을 λ•Œ μ»€μŠ€ν…€ 훅을 주둜 μ‚¬μš©ν•œλ‹€. 이λ₯Ό μ΄μš©ν•˜λ©΄

  1. μƒνƒœκ΄€λ¦¬ 둜직의 μž¬ν™œμš©μ΄ κ°€λŠ₯ν•˜κ³ 
  2. 클래슀 μ»΄ν¬λ„ŒνŠΈλ³΄λ‹€ 적은 μ–‘μ˜ μ½”λ“œλ‘œ λ™μΌν•œ λ‘œμ§μ„ κ΅¬ν˜„ν•  수 있으며
  3. ν•¨μˆ˜ν˜•μœΌλ‘œ μž‘μ„±ν•˜κΈ° λ•Œλ¬Έμ— 보닀 λͺ…λ£Œν•˜λ‹€λŠ” μž₯점이 μžˆλ‹€. (e.g. useSomething)
//FriendStatus : μΉœκ΅¬κ°€ online인지 offline인지 returnν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ
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 : μΉœκ΅¬κ°€ online일 λ•Œ μ΄ˆλ‘μƒ‰μœΌλ‘œ ν‘œμ‹œν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ
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>
  );
}

FriendStatus μ»΄ν¬λ„ŒνŠΈλŠ” μ‚¬μš©μžλ“€μ΄ μ˜¨λΌμΈμΈμ§€ μ˜€ν”„λΌμΈμΈμ§€ ν™•μΈν•˜κ³ , FriendListItem μ»΄ν¬λ„ŒνŠΈλŠ” μ‚¬μš©μžλ“€μ˜ μƒνƒœμ— 따라 온라인이라면 μ΄ˆλ‘μƒ‰μœΌλ‘œ ν‘œμ‹œν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλ‹€. 이 두 μ»΄ν¬λ„ŒνŠΈλŠ” μ •ν™•ν•˜κ²Œ λ˜‘κ°™μ΄ μ“°μ΄λŠ” 둜직이 μ‘΄μž¬ν•˜κ³  μžˆλ‹€. 이 λ‘œμ§μ„ λΉΌλ‚΄μ„œ 두 μ»΄ν¬λ„ŒνŠΈμ—μ„œ κ³΅μœ ν•  μˆ˜λŠ” μ—†μ„κΉŒ? Custom Hook을 μ‚¬μš©ν•œλ‹€λ©΄ κ°€λŠ₯ν•˜λ‹€.

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

두 μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ‚¬μš©ν•˜κΈ° μœ„ν•΄ λ™μΌν•˜κ²Œ μ‚¬μš©λ˜κ³  μžˆλŠ” λ‘œμ§μ„ λΆ„λ¦¬ν•˜μ—¬ ν•¨μˆ˜ useFriendStatus둜 λ§Œλ“ λ‹€.

✨ Custom Hook을 μ •μ˜ν•  λ•Œμ˜ κ·œμΉ™

  • ν•¨μˆ˜ 이름 μ•žμ— useλ₯Ό λΆ™μ΄λŠ” 것
  • λŒ€κ°œμ˜ 경우 ν”„λ‘œμ νŠΈ λ‚΄μ˜ hooks 디렉토리에 Custom Hook을 μœ„μΉ˜ μ‹œν‚¨λ‹€.
  • Custom Hook으둜 λ§Œλ“€ λ•Œ ν•¨μˆ˜λŠ” 쑰건뢀 ν•¨μˆ˜κ°€ μ•„λ‹ˆμ–΄μ•Ό ν•œλ‹€. 즉 return ν•˜λŠ” 값은 μ‘°κ±΄λΆ€μ—¬μ„œλŠ” μ•ˆ λœλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— μœ„μ˜ 이 useFriendStatus Hook은 온라인 μƒνƒœμ˜ μ—¬λΆ€λ₯Ό boolean νƒ€μž…μœΌλ‘œ λ°˜ν™˜ν•˜κ³  μžˆλ‹€.

μ΄λ ‡κ²Œ λ§Œλ“€μ–΄μ§„ Custom Hook은 Hook 내뢀에 useState와 같은 React λ‚΄μž₯ Hook을 μ‚¬μš©ν•˜μ—¬ μž‘μ„±ν•  수 μžˆλ‹€. 일반 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ” React λ‚΄μž₯ Hook을 뢈러 μ‚¬μš©ν•  수 μ—†μ§€λ§Œ Custom Hook μ—μ„œλŠ” κ°€λŠ₯ν•˜λ‹€λŠ” 것 λ˜ν•œ μ•Œμ•„λ‘λ©΄ 쒋을 점이닀.

이제 이 useFriendStatus Hook을 두 μ»΄ν¬λ„ŒνŠΈμ— μ μš©ν•΄λ³΄μž!

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

λ‘œμ§μ„ 뢄리해 Custom Hook으둜 λ§Œλ“€μ—ˆκΈ° λ•Œλ¬Έμ— 두 μ»΄ν¬λ„ŒνŠΈλŠ” 더 μ§κ΄€μ μœΌλ‘œ 확인이 κ°€λŠ₯해진닀.

κ·ΈλŸ¬λ‚˜ 같은 Custom Hook을 μ‚¬μš©ν–ˆλ‹€κ³  ν•΄μ„œ 두 개의 μ»΄ν¬λ„ŒνŠΈκ°€ 같은 stateλ₯Ό κ³΅μœ ν•˜λŠ” 것은 μ•„λ‹ˆλ‹€. κ·Έμ € 둜직만 κ³΅μœ ν•  뿐, stateλŠ” μ»΄ν¬λ„ŒνŠΈ λ‚΄μ—μ„œ λ…λ¦½μ μœΌλ‘œ μ •μ˜ λ˜μ–΄ μžˆλ‹€.

0개의 λŒ“κΈ€