Hooks API Reference(2)

Doum Kim·2020년 3월 27일
0

React - 기초

목록 보기
6/20
post-thumbnail

추가 Hook

useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init);

useState의 대체 함수, 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리할 수 있다. 상태 업데이트 로직을 컴포넌트 바깥으로 빼거나 다른 파일에 작성해 불러와서 사용 가능하다.

useState를 사용한 Counter 예제

import React, { useState } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleIncrease = () => {
    setCount(prevCount => (prevCount += 1));
  };
  const handleDecrease = () => {
    setCount(prevCount => (prevCount -= 1));
  };

  return (
    <>
      <h1>{count}</h1>
      <button onClick={handleIncrease}>+1</button>
      <button onClick={handleDecrease}>-1</button>
    </>
  );
};

export default Counter;
}

useReducer를 사용한 Counter 예제

import React, { useReducer } from "react";

const reducer = (state, action) => {
  switch (action.type) {
    case "INCREASE":
      return { ...state, count: action.count };
    case "DECREASE":
      return { ...state, count: action.count };
    default:
      throw new Error(`Unhandled error : ${action.type}`);
  }
};

const Counter = () => {
  const [state, dispatch] = useReducer(reducer, {
    count: 0
  });

  const { count } = state;

  const handleIncrease = () => {
    dispatch({ type: "INCREASE", count: count + 1 });
  };
  const handleDecrease = () => {
    dispatch({ type: "DECREASE", count: count - 1 });
  };

  return (
    <>
      <h1>{count}</h1>
      <button onClick={handleIncrease}>+1</button>
      <button onClick={handleDecrease}>-1</button>
    </>
  );
};

export default Counter;

이런식으로 useState를 useReducer로 변경이 가능하다.

useState, useReducer를 상황에 맞게 잘 선택하는게 좋다.
state가 컴포넌트에 하나거나 단순한 값이라면 useState가 좋은 선택이고, 만약 컴포넌트에서 관리하는 값이 여러개 또는 상태의 구조가 복잡해지면 useReducer를 선택하는게 좋다.

useCallback

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

props로 넘겨주는 함수는 useCallback이 필수이다. 그 이유는 함수형 컴포넌트는 state가 바뀔 때 마다 코드가 전체 재 실행이 된다. 즉 함수가 재 생성이 되는 것이다. 따라서 그 함수를 props로 받는 자식 컴포넌트들이 불필요한 렌더링이 발생하게 되는 것이다.

useCallback은 이러한 불필요한 렌더링을 방지하기 위해 메모이제이션이된 콜백을 반환한다. deps 값을 배열에 넣어 전달한다.콜백함수의 메모이제이션된 버전을 반환하고 그 메모이제이션된 버전은 콜백의 deps에 넣어 준 값이 변경되었을 때에만 변경된다.

즉 불필요한 렌더링 방지를 위해 참조의 동일성에 의존적인 최적화된 자식 컴포넌트에 콜백을 전달할 때 유용하게 쓰인다.

useCallback(fn, deps)은 useMemo(() => fn, deps)와 같다.

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

메모이제이션된 값을 반환한다. 위의 useCallback과 같이 deps 배열에 의존성 값을 넣어준다.
의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산을 한다. 물론 useMemo도 성능 최적화를 위한 방법이다.

useRef

const refContainer = useRef(initialValue);
  1. 컴포넌트 안에서 조회 및 수정 할 수 있는 변수를 관리하는 용도
    useRef로 관리하는 변수는 값이 변해도 컴포넌트가 다시 렌더링되지 않는다. 리액트 컴포넌트에서 상태는 상태를 바꾸는 함수를 호출해 리렌더링 후의 업데이트 된 상태를 조회할 수 있지만 useRef로 관리하는 변수는 설정 후 바로 조회 가능하다.
    • 외부 라이브러리를 사용하여 만들어진 인스턴스
    • setTimeout, setInterval을 통해서 만들어진 id
  1. 특정 DOM 선택하는 용도
    • 엘리먼트의 크기 가져오기
    • 스크롤바 위치 가져오기
    • 포커스 설정 등...

0개의 댓글