React Hook

키워드

- React Hook 이란
- Hooks
    - useState
    - useEffect
    - useContext
    - useRef
    - useLayoutEffect
- React StrictMode 란

Hook의 개요

Hook 개요

Hooks API Reference

React 16.8에서 Hooks가 도입됨. 기존 방식에 있던 몇 가지 문제를 해결.

React Conf 2018 Hooks 소개 영상

기존 방식의 문제점:

  • Wrapper Hell (HoC)

Wrapper Hell
  • Huge Components

  • Confusing Classes

고차 컴포넌트라고 부르며, 컴포넌트 로직을 재사용하기 위한 React의 고급 기술이다.


React를 쓰는 방식을 완전히 바꾼 커다란 변화. → 이제는 예전으로 돌아가는 게 불가능하다!


기존


현재

  • 그냥 Function Component만 사용.

  • 상태 관리 유무를 바로 알기 어려움 = 신경쓰지 않아도 됨.

  • 복잡한 요소는 전부 Hook으로 격리 및 재사용 가능.


대표적인 Hooks

기본 Hook

  • useState → State Hook ⇒ React의 State

  • useEffect ⇒ Side-effect

  • useContext


부가 Hook

  • useRef

  • 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할 때 주의사항

Last updated