React 내장 Hooks
State Hook
import React, { useState } from 'react';
function Example() {
// "count"라는 새 상태 변수를 선언합니다
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- 위에서 useState 가 바로 Hook 입니다.
- Hook를 호출해 함수컴포넌트 안에 State를 추가했습니다. ( 다시 렌더링 되어도 그대로 유지 됨 )
- 클래스 컴포넌트의 this.state 와 달리 setState Hook의 state는 객체일 필요가 없습니다.
Effect Hook
- 데이터를 가져오거나 DOM을 직접 조작하는 다른 컴포넌트에 영향을 줄 수 있고 렌더링 과정에서 구현할 수 없는 작업을 "side effect" 혹은 "effect" 라고 합니다.
- useEffect 는 함수 컴포넌트 내에서 이런 side effect를 수행할 수 있게 해줍니다.
- 클래스 컴포넌트의 componentDidMount, componentDidUpdate, componentWillUnmount가 하나의 API 로 통합됬다고 볼 수 있습니다.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 비슷합니다
useEffect(() => {
// 브라우저 API를 이용해 문서의 타이틀을 업데이트합니다
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- React는 DOM을 조작한 후에 "effect" 함수를 실행합니다.
- useEffect는 컴포넌트 안에 선언되어 있기 때문에 props 와 state에 접근 할 수 있습니다.
- 매 랜더링 시 실행됩니다.
Effect 해제하기
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
- 컴포넌트가 unmount 될 때 ChatAPI는 구독을 해지합니다.
- 재 렌더링이 일어나 effect를 재 실행하기 전에도 구독을 해지합니다.
- 클래스 컴포넌트는 서로 관련있는 구독 추가/제거 로직을 생명주기 메소드 각각에 쪼개서 넣어야 했지만 Hook는 코드들을 한군데에 모아서 작성 할 수 있습니다.
Hook 사용 규칙
- 함수 컴포넌트 혹은 custom Hook 에서만 Hook를 호출해야 합니다.
나만의 Hook 만들기
- 상태 관련 로직을 컴포넌트 간에 재사용하고 싶을때 고차 컴포넌트나 render props를 사용했지만 custom hook 는 컴포넌트 트리에 새 컴포넌트를 추가하지 않고도 이것을 가능하게 해줍니다.
import React, { useState, useEffect } from 'react';
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
};
});
return isOnline;
}
- useFriendStatus 라는 customHook는 friendID를 인자로 받아서 친구의 접속 상태를 반환해줍니다.
function FriendListItem(props) {
const isOnline = useFriendStatus(props.friend.id);
return (
<li style={{ color: isOnline ? 'green' : 'black' }}>
{props.friend.name}
</li>
);
}
- 위와 같이 useFriendStatus는 다른 컴포넌트에서도 사용할 수 있습니다.
- Hook 호출은 완전히 독립된 state를 가집니다. 즉 한 컴포넌트 안에서 같은 custom Hook을 두번 쓸 수도 있습니다.
- custome hook의 이름이 "use"로 시작하는건 convention 입니다.
댓글