728x90
Custom Hook
- 여러 컴포넌트에서 반복적으로 사용되는 로직을 Custom Hook으로 만들어 재사용할 수 있다.
- 이름은 반드시 use로 시작한다.
- 내부에서 다른 Hook을 호출하는 하나의 자바스크립트 함수이다.
import React, { useState, useEffect } from "react";
function UserStatus(props) {
const [isOnline, setOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
return () => {
ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
};
});
if (isOnlinde === null) {
return '대기중...';
}
return isOnlinde ? '온라인' : '오프라인';
}
- 이 코드에 나오는 UserStatus라는 컴포넌트는 isOnline이라는 state에 따라서 사용자의 상태가 온라인인지 아닌지를 텍스트로 보여주는 컴포넌트이다.
- 동일한 웹사이트에서 연락처 목록을 제공하는데 이때 온라인인 유저는 초록색으로 표시하고 싶다고 가정해 보자.
import React, { useState, useEffect } from "react";
function UserListItem(props) {
const [isOnline, setOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
return () => {
ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
};
});
return (
<li style={{ color: isOnlinde ? 'green' : 'black' }}>
{props.user.name}
</li>
);
}
- 이를 수행할 컴포넌트의 이름을 UserListItem이라고 지었다.
- 코드를 보면 앞에 나오는 useStatus와 useState, useEffect 부분이 똑같다는 것을 확인할 수 있다.
- 이제 이 중복된 부분을 추출하여 Custom Hook을 만들어보자.
Custom Hook 추출하기
import React, { useState, useEffect } from "react";
function useUserStatus(props) {
const [isOnline, setOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
return () => {
ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
};
});
return isOnline;
}
- 위 두 코드에서 중복된 부분을 추출한 컴포넌트이다.
- Custom Hook은 별다른 규칙이 없다. 파라미터로 무엇을 받을지, 어떤 것을 리턴해야 할지를 개발자가 정할 수 있다.
- 이런 점에서 Custom Hook은 단순한 함수와도 같다고 할 수 있다.
- 단, 이름을 Use로 시작해 이것이 단순한 함수가 아닌 리액트 Hook이라는 것을 나타내준다.
Custom Hook 사용하기
function UserStatus(props) {
const isOnline = useUserStatus(props.user.id);
if (isOnlinde === null) {
return '대기중...';
}
return isOnlinde ? '온라인' : '오프라인';
}
function UserListItem(props) {
const isOnline = useUserStatus(props.user.id);
return (
<li style={{ color: isOnline ? 'greem' :'black' }}>
{props.user.name}
</li>
);
}
- Custom Hook의 이름은 꼭 use로 해야 한다.
- 여러 개의 컴포넌트에서 하나의 Custom Hook을 사용할 때 컴포넌트 내부에 있는 모든 state와 effects는 분리되어 있다.
- 리액트 컴포넌트는 각각의 Custom Hook 호출에 대해서 분리된 state를 얻게 되기 때문이다.
- 각 Custom Hook의 호출 또한 완전히 독립적이다.
Hook 간에 데이터를 공유하는 방법
Const userList = [
{id : 1, name: 'kane'},
{id : 1, name: 'son'},
{id : 1, name: 'lukas'},
];
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.id}
</option>
))}
</select>
</>
);
}
- 이 컴포넌트는 select 태그를 통해 목록에서 사용자를 선택할 수 있게 하고, 사용자를 선택할 경우 사용자가 온라인인지 아닌지를 보여주게 된다.
const [userId, setUserId] = useState(1);
const isUserOnline = useUserStatus(userId);
- 위 코드에서 이 부분을 보면 useState() Hook을 사용해서 useId라는 state를 만들었다. 현재 선택된 사용자의 아이디를 저장하기 위한 용도이다.
- 이 userId는 다음에 나오는 useUserStatus()의 파라미터 값으로 들어가게 된다.
- 이렇게 하면 setUserId() 함수를 통해 userId가 변경될 때마다 useUserStatus() Hook은 이전에 선택된 사용자를 구독 취소하고 새로운 선택된 사용자의 온라인 여부를 구독하게 된다.
- Hook 간의 데이터 공유는 이러한 방식으로 진행된다.
참고
인프런 - 처음 만난 리액트
728x90
'[FrontEnd] > React' 카테고리의 다른 글
React - Conditional Rendering과 Inline Conditions (3) | 2023.07.01 |
---|---|
React - Handling Events (0) | 2023.06.17 |
React - Hooks (0) | 2023.06.02 |
React - State & Lifecycle (0) | 2023.06.02 |
React - Components & Props (0) | 2023.06.02 |