Hook은 React 16.8에 새로 추가된 사항으로, 컴포넌트로 부터 상태 관련 로직을 추상화 할 수 있다. 독릭접인 테스트와 재사용이 가능하다.
계층 변화 없이 상태 관련 로직을 재사용 할 수 있도록 도와주고 Class 없이 Functional (함수 컴포넌트)만으로도 React 기능들을 사용하는 방법을 알려준다.
함수 컴포넌트에서 state와 lifecycle을 사용 할 수 있게 해주는 함수이다.
React Hook의 모든것 링크
최상위에서만 Hook을 호출해야 한다. 반복문, 중첩문, 조건문의 함수 내에서 Hook을 실행하면 안된다.
React 함수 컴포넌트 내에서만 Hook을 호출해야 한다.
일반 javascript함수에서는 호출 하면 안된다.
useState라는 Hook을 호출해 함수 컴포넌트 안에 state를 추가한다. 현재의 state 값과 이 값을 업데이트 하는 함수를 쌍으로 제공한다. 인자로는 초기 state 값을 하나 받는다.
import React, { useState } from 'react';
function Examples() {
const [count, setCount] = useState(0);
// 카운터는 0부터 시작하기 때문에 초기값을 0으로 설정
const [age, setAge] = useState(42);
const [fruit, setFruite] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Study'}]);
return (
<div>
<p>You clicked {count} times</p>
<buttonn onClick={() => setCount(count + 1)}></button>
// ...
</div>
useEffect는 함수 컴포넌트 내에서 데이터를 가져오거나 구독하고 DOM을 직접 조작하는 작업을 할 수 있게 해준다.
class의 componentDidMount, componenDidUpdate, componentWillMount와 같은 목적으로 제공되지만 하나의 API로 통합된 것이다. useState와 마찬가지로 여러 개의 effect를 사용가능하다.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `clicked ${count} times`
});
// DOM을 업데이트 한뒤에 문서의 타이틀을 바꾸는 컴포넌트
return (
// ...
)
}
만약 effect를 해제할 필요가 있다면, 해제하는 함수를 반환해주면 된다.
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(Status.isOnline);
}
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscirbeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if(isOnline === null) {
return 'Loading...';
}
return isOnlie ? 'Online' : 'OffLine';
}
// 컴포넌트가 unmount 될때 ChatAPI에서 구독을 해지.
// 재 렌더링이 일어나 effect를 재실행하기 전에도 구독을 해지.
컴포넌트를 중첩하지 않고도 React context를 구독할 수 있게 해준다.
상태 관련 로직을 컴포넌트 간에 재사용 하고 싶은 경우, Custom Hook을 사용하면 새 컴포넌트를 추가 하지 않고, 또한 기존의 higher-order components와 render props를 사용 안해도 된다.
Custom Hook은 컨벤션에 가깝다. hook의 여러가지 문법을 이용해 본인이 커스텀한 hook을 만들어 다른 컴포넌트에서 함수나 state의 추가 생성없이 간단하게 사용할 수 있다.
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 라는 custom Hook 생성
// firendID를 인자로 받아 친구의 접속 상태를 반환
이제 여러 컴포넌트에서 사용 가능하다
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>
);
}