키워드
- React Hook 이란
- Hooks
- useState
- useEffect
- useContext
- useRef
- useLayoutEffect
- React StrictMode 란
Hook의 개요
Hook 개요
Hooks API Reference
React 16.8에서 Hooks가 도입됨. 기존 방식에 있던 몇 가지 문제를 해결.
React Conf 2018 Hooks 소개 영상
기존 방식의 문제점:
고차 컴포넌트라고 부르며, 컴포넌트 로직을 재사용하기 위한 React의 고급 기술이다.
React를 쓰는 방식을 완전히 바꾼 커다란 변화. → 이제는 예전으로 돌아가는 게 불가능하다!
기존
상태를 가진 컴포넌트는 Class Component로 만들고, props만 사용하는 재사용이 용이한 작은 컴포넌트는 Function Component로 작성.
현재
그냥 Function Component만 사용.
상태 관리 유무를 바로 알기 어려움 = 신경쓰지 않아도 됨.
복잡한 요소는 전부 Hook으로 격리 및 재사용 가능.
대표적인 Hooks
기본 Hook
useState → State Hook ⇒ React의 State
부가 Hook
useLayoutEffect → useEffect와 조금 다름.
...
useEffect
Synchronizing with Effects
You Might Not Need an Effect
Using the Effect Hook
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할 때 주의사항