Hook : class를 작성하지 않고도 state와 다른 react의 기능들을 사용할 수 있게 해준다.
하위 호환성을 가지고 있다.
함수 컴포넌트에서 React state와 생명주기 기능을 연동(hook into) 할 수 있게 해주는 함수이다. Hook은 클래스 안에서는 동작하지 않으며 class없이 react를 사용할 수 있도록 하는 것이다.
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을 의미한다. Hokk을 호출해 함수 컴포넌트 안에 state를 추가했으며 이 state는 컴포넌트가 다시 렌더링되어도 그대로 유지될 것이다. useState는 현재 state 값과 이 값을 업데이트 하는 함수를 쌍으로 제공한다. 이 함수를 이벤트 핸들러나 다른 곳에서 호출할 수 있다. 이것은 class의 this.setState와 거의 유사하지만 이전 state와 새로운 state를 합치지 않는 다는 차이점을 갖는다.
useState는 인자로 초기 state 값 을 하나 받고 this.state와는 달리 setState의 Hook의 state는 객체일 필요가 없다. 초기값은 첫번째 렌더링에서 한번만 사용된다.
여러 state변수 선언
function ExampleWithManyStates() {
// 상태 변수를 여러 개 선언했습니다!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
}
배열 구조분해 문법을 통해 useState로 호출된 state 변수들을 다른 변수명으로 할당 할 수 있게 해준다.
Effect Hook
리액트 컴포넌트 안에서 데이터를 가져오거나 구독하고 DOM을 직접 조작하는 동작을 side effects라고 한다. 이것은 다른 컴포넌트에 영향을 줄 수도 있고, 렌더링 과정에서는 구현할 수 없는 작업이기 때문이다.
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>
);
}
기본적으로 리액트는 매 렌더링 이후에 effects를 실행한다. 위에서 Effects는 컴포넌트 안에 선언되었기 때문에 props와 state에 접근 할 수 있다.
이펙트 해지는 옵션으로 함수를 통해 가능하다.
Hook 사용규칙
최상위에서만 호출해야하며 반복문, 조건문, 중첩 된 함수 내에 Hook을 실행해서는 안된다.
React 함수 컴포넌트 내에서만 호출하며 일반 javascript 함수 내에서는 호출해서 안된다.
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;
}
function FriendStatus(props) {
const isOnline = useFriendStatus(props.friend.id);
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
댓글