[React Basic] Custom Hook

Joah·2022년 9월 23일
0

React Basic

목록 보기
20/25

게시글은 리액트 공부용이며 출처를 제시합니다.
출처: 소플의 처음 만난 React, 리액드를 다루는 기술, 모던 자바스크립트 deep dive

Custom Hook을 만드는 이유

리액트에서 기본적으로 제공되는 훅 이외 추가적으로 필요한 기능을 사용하기 위해 직접 만든다.

여러 컴포넌트에서 반복적으로 사용되는 로직을 훅으로 만들어 재사용하기 위함이다.


🛼 Custom Hook을 만들어야 하는 상황

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

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

사용자의 상태에 따라 온라인인지 오프라인인지 텍스트로 나타내는 UserStatus 컴포넌트가 있다.

같은 웹 페이지에서 다른 컴포넌트에서 온라인인 사용자의 이름은 초록색을 표시하고 싶다면 위의 함수를 똑같이 적용해야 한다. return문 만 달라질 뿐

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

이렇게 중복되는 코드가 발생하면 커스텀 훅을 사용할 수 있다.


🛼 Custom Hook 추출하기

import {useState, useEffect} from "react";

function useUserStatus(userId){
	const [isOnline, setIsOnline] = useState(null);
  
    
    useEffect(()=>{
      const handleStatusChange = (status) => {
    	setIsOnline(status.isOnline)
    	}
    	ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
      return()=>{
      	ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
      };
    });
  
  return isOnline;
}
  • 이름은 use로 시작한다.

  • 이전 게시글인 훅을 사용할 때 지킬 두가지 규칙이 적용된다. 커스텀 훅도 훅이기 때문이다.

useUserStatus() 훅의 목적은 사용자의 온라인/오프라인 상태를 구독하는 것이기 대무에 파라미터로 userId를 받도록 한다.


🛼 Custom Hook 사용하기

function UserStatus(props){
	const inOnline = useUserStatus(props.user.id);
  
  	if (isOnline === null) {
    	return '대기 중...';
    }
  return isOnline ? "온라인" : "오프라인";
}

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

커스텀 훅은 리액트 기능이 아닌 훅의 디자인에서 자연스럽게 따르는 규칙이다.

하지만 use는 반드시 따라야한다. 만약 이름이 use로 시작하지 않는다면 특정 함수의 내부에서 훅을 호출하는지를 알 수 없기 때문에 훅의 규칙 위반 여부를 자동으로 확인할 수 없게 된다.


그럼 같은 커스텀 훅을 사용하는 컴포넌트들을 state를 공유하나?

🚫 아니요!!!
커스텀 훅은 단순히 state와 연관된 로직을 재사용 가능하게 만든 것이다.
따라서 여러 개의 컴포넌트에서 하나의 커스텀 훅을 사용할 때에 컴포넌트 내부에 있는 모든 state와 effects는 전부 분리되어 있다.

HOW?
각각의 커스텀 훅 호출에 대해서 분리된 state를 얻게 된다. 따라서 커스텀 훅의 호출은 완전히 독립적이다.


그럼 훅들 사이에서 같은 데이터를 공유하고 싶다면?

const userList = [
  {id: 1, name: 'Joah'},
  {id: 2, name: 'Mike'},
  {id: 3, name: 'Dustin'}
]

function ChatUserSelector(props){
	const [userId, setUserId] = useState(1);
  	const isUserOnline = useUserStatus(userId);
  
  return (
  	<>
    	<Circle color={isUserOnline? 'green' : 'red'}/>
		<select
			value={userId}
			onChange={event => setUserId(Number(event.target.value))}
		>
          {userList.map(user=> (
           	<option key={user.id} value={user.id}>
              {user.name}
			</option>
           ))}
    	</select>
    </>
  );
}

select 태그를 통해 목록에서 사용자를 선택할 수 있게 하고 있으며 사용자를 선택할 경우 해당 사용자가 온라인인지 아닌지 색깔로 보여준다.

useState를 사용해서 userId라는 state를 만든다.
현재 선택된 사용자의 아이디를 저장하기 위함이다.
userIduseUserStatus 훅의 파라미터로 들어가게 된다. 그럼 setUserId 함수를 통해 userId가 변경될 때마다 useUserStatus 훅은 이전에 선택된 사용자를 구독 취소하고 새로 선택된 사용자의 온라인 여부를 구독하게 된다. 이렇게 훅들 사이에서 데이터를 공유할 수 있다.

profile
Front-end Developer

0개의 댓글