React Hook
키워드
- React Hook 이란
- Hooks
- useState
- useEffect
- useContext
- useRef
- useLayoutEffect
- React StrictMode 란
React 16.8에서 Hooks가 도입됨. 기존 방식에 있던 몇 가지 문제를 해결.
기존 방식의 문제점:

Huge Components
Confusing Classes
고차 컴포넌트라고 부르며, 컴포넌트 로직을 재사용하기 위한 React의 고급 기술이다.
React를 쓰는 방식을 완전히 바꾼 커다란 변화. → 이제는 예전으로 돌아가는 게 불가능하다!
기존
상태를 가진 컴포넌트는 Class Component로 만들고, props만 사용하는 재사용이 용이한 작은 컴포넌트는 Function Component로 작성.
Redux에서도 비슷한 구분이 존재했다.
현재
그냥 Function Component만 사용.
상태 관리 유무를 바로 알기 어려움 = 신경쓰지 않아도 됨.
복잡한 요소는 전부 Hook으로 격리 및 재사용 가능.
대표적인 Hooks
기본 Hook
useState → State Hook ⇒ React의 State
useEffect ⇒ Side-effect
useContext
부가 Hook
useRef
useLayoutEffect → useEffect와 조금 다름.
...
useEffect
useEffet의 경우, 외부(external sytem)와 동기화(Synchronize)하지 않는 이상 쓰지 말것
useEffect 함수를 return 함으로서 종료 처리를 할 수 있음.
의존성 배열에서 아무 것도 지정하지 않으면 맨 처음에 딱 한번만 실행하게 할 수 있다.
주로 API를 호출해서 데이터를 얻을 때 사용한다.
타이머 예제
React의 외부에 우아하게 접근. 이 정도는 useEffect를 안 쓴다고 크게 문제가 되지 않지만, 이렇게 쓰는 습관을 들이자.
useEffect(() => {
document.title = `Now: ${new Date().getTime()}`;
});
타이머를 on/off하는 기능을 그냥 만들면 문제가 발생한다.
function Timer() {
useEffect(() => {
setInterval(() => {
document.title = `Now: ${new Date().getTime()}`;
}, 100);
});
return (
<p>Playing</p>
);
}
export default function TimerControl() {
const [playing, setPlaying] = useState(false);
const handleClick = () => {
setPlaying(!playing);
};
return (
<div>
{playing ? (
<Timer />
) : (
<p>Stop</p>
)}
<button type="button" onClick={handleClick}>
Toggle
</button>
</div>
);
}
종료 처리
useEffect(() => {
const savedTitle = document.title;
const id = setInterval(() => {
document.title = `Now: ${new Date().getTime()}`;
}, 100);
return () => {
document.title = savedTitle;
clearInterval(id);
};
});
처음에 한번만 실행하기
의존성 배열에서 아무 것도 지정하지 않으면 맨 처음에 딱 한번만 실행하게 할 수 있다.
주로 API를 호출해서 데이터를 얻을 때 사용한다.
const [products, setProducts] = useState<Product[]>([]);
useEffect(() => {
const fetchProducts = async () => {
const url = 'http://localhost:3000/products';
const response = await fetch(url);
const data = await response.json();
setProducts(data.products);
};
fetchProducts();
}, []);
Fetch 함수의 위치가 고민된다면, Dan Abramov의 글을 다시 보자.
처음에 한번만 실행하기
의존성 배열에서 아무 것도 지정하지 않으면 맨 처음에 딱 한번만 실행하게 할 수 있다.
주로 API를 호출해서 데이터를 얻을 때 사용한다.
const [products, setProducts] = useState<Product[]>([]);
useEffect(() => {
const fetchProducts = async () => {
const url = 'http://localhost:3000/products';
const response = await fetch(url);
const data = await response.json();
setProducts(data.products);
};
fetchProducts();
}, []);
Fetch 함수의 위치가 고민된다면, Dan Abramov의 글을 다시 보자.
Effect가 두 번 실행되는 문제
<React.StrictMode>로 컴포넌트 전체를 감쌀 경우, 예상치 못한 Side Effect를 찾으려고 Effect 등을 두 번씩 실행함. 평소에는 큰 문제가 없지만, API 등을 사용하면 이상하다고 느낄 수 있으니 참고할 것.
의존성 배열을 이용해 Fetch할 때 주의사항
Last updated