2019-07-14 TIL

2019-07-14

React - Hooks 조금

그냥 아주 조금

useState

  • useState 는 새 state를 기존 state와 merge하지 않음!

    기존 setState와 다른 중요한 점이다. 기존 state를 새 state로 갈아치운다. (물론 useState 호출하며 짝지어 선언한 state만 건드린다)

  • 선언한 state 변수를 유지시켜준다.

    어찌보면 당연한, 내부 동작이라고 볼 수 있다. 렌더마다 컴포넌트 함수가 새로 실행되므로 어떤 장치가 없다면 안에 선언한 state 변수의 내용이 계속해서 초기화될 수도 있는데, 이 부분을 우리가 기대하는 대로 동작하게 하는 것이다.

useCallback

함수형 컴포넌트 안에 선언한 함수는 매 렌더마다 새로 생성된다. (클래스 컴포넌트와 다르게, return이 곧 render될 view라는 점을 생각해보자.)

이벤트 핸들러 함수는 텍스트 인풋이나 마우스 움직임, 스크롤 변화 등 연속적이고 빠르게 발생하는 이벤트를 처리하곤 하는데, 이 이벤트에 의한 수많은 렌더링 시점에 함수를 새로 생성하는 것은 분명한 비효율이다.

useCallback를 사용하면, 특정 시점에만 함수를 선언해놓고 이용할 수 있게 된다.

다시 말해, 위에 언급한 동일 함수의 반복 생성을 막아준다.

useCallback을 사용해 이벤트 핸들러를 선언하는 습관을 들이는 것이 좋겠다.

Custom Hooks

로직에 해당하는 부분을 따로 묶어 또다른 훅처럼 사용하는 패턴을 말한다.

import React, { useState } from "react";

const useClickCount = initialClicks => {
  const [clicks, setClicks] = useState(initialClicks);
  const increment = () => setClicks(clicks + 1);
  return [clicks, increment];
};

const Counter = () => {
  const [clicksA, incrementA] = useClickCount(0);
  const [clicksB, incrementB] = useClickCount(0);

  return (
    <>
      <p>{clicksA} A clicks <button onClick={incrementA}>Click A</button></p>
      <p>{clicksB} B clicks <button onClick={incrementB}>Click B</button></p>
    </>
  );
}

출처: https://medium.com/trabe/react-16-7-753c61ca7a1e

간단한 예제라 custom hooks가 뭔지 알기엔 좋다.

custom hooks를 잘 만들어 활용하려면 머릴 좀 굴려야겠다.

useEffect

이건 좀 신기해서 퍼옴

import React, { useState, useEffect } from "react";

const SizeWrapper = ({ children }) => {  
  const [size, setSize] = useState({ height: window.innerHeight, width: window.innerWidth });

  useEffect(() => {
    const handleResize = () => setSize({ height: window.innerHeight, width: window.innerWidth });
    
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return children(size);
}

<SizeWrapper>
  {({ height, width }) => (
    <>
      <p>Height = {height}</p>
      <p>Width = {width}</p>
    </>
  )}
</SizeWrapper>

출처: https://medium.com/trabe/react-16-7-753c61ca7a1e

children을 이렇게도 쓸 수 있구나!!

근데 가만보면 함수형 컴포넌트를 children으로 받은것과 같다.

아, 원래 이 코드의 요점은 useEffect를 사용해 첫 렌더 시 이벤트 리스너를 달아줬고, cleanup function을 return하도록 작성해 unsubscribe에 쓸 수 있다는 것임. (각각 componentDidMount, componentWillUnmount에 해당)

Hooks의 장점, rule

아래 그림은 Dan Abramov가 ReactConf2018 발표에 사용한 코드를 visualization한 것이다. (출처에 가면 gif로 볼 수 있다)

출처: https://twitter.com/prchdk/status/1056960391543062528

요지는, lifecycle method 안에 각각 뜯어져 있는 로직을 custom hooks 등을 이용해 묶어줄 수 있다는 것이고, 이렇게 만든 로직을 추출해 재사용할 수 있다는 것이다.


hooks의 규칙 두가지 적으며 마무리한다.

  • hooks는 컴포넌트의 top-level scope에서만 사용하자
  • hooks는 함수형 컴포넌트에서만 사용 가능

위 규칙들은 공식 lint가 있으니 적용해 코딩하는것이 이득이다.


hooks관련 좋은 레포


Minchang Kim
Minchang Kim
웹/앱 개발자 김민창입니다! 좋은 하루 되세요!