리액트 훅을 통한 최적화 - 기본편

js·2022년 2월 23일
0

리액트 최적화

목록 보기
4/5

3줄요약

useMemo => 복잡한 함수의 결과값을 기억한다.

React.memo => 컴퍼넌트의 props가 바뀔 때에만 re-render되게 한다.

useCallback => usecallback 안에 함수 정의를 넣으면 불필요한 함수 생성 및 실행을 막을 수 있다.

useRef => dom 접근이나 단순한 값을 저장한다.

본문

리액트에서는 렌더링이 되는 대표적인 조건이 몇 가지 있다.

  • state 변경이 있을 때
  • 부모 컴포넌트가 렌더링 될 때
  • 새로운 props이 들어올 때
  • shouldComponentUpdate에서 true가 반환될 때
  • forceUpdate가 실행될 때

이 중에서 1번과 2번은 얕은 비교를 통해 새로운 값인지 여부를 따져 리렌더링을 한다고 한다.
참고로 클래스 컴포넌트에서는 렌더링이 될 경우, render 메서드만 리 렌더링이 되지만, 함수형 컴포넌트(훅스)에서는 위 조건 중에 하나라도 될 경우 함수 전체가 재실행이 된다.

숫자, 문자열, 객체처럼 일반 값을 재사용하려면 useMemo를 사용하고, 함수를 재사용하려면 useCallback을 사용

useMemo

useMemo => 복잡한 함수 결괏값을 기억

렌더링하는 과정에서 특정 값이 바뀌었을 때만 연산을 실행하고, 원하는 값이 바뀌지 않았다면 이전에 연산했던 결과를 다시 사용하는 방식

React.memo는 shouldComponentUpdate라이프 사이클이 기본으로 내장된 함수형 컴포넌트라고 생각하면 된다. 얕은 비교 연산을 통해 동일한 참조 값의 prop이 들어온다면 리 렌더링을 방지시킨다.

  1. useCallback: 함수 자체를 기억하고 있음

useCallback

사용하는 이유

현재 하위 컴포넌트에 전달하는 콜백 함수를 inline 함수로 사용하고 있다거나, 컴포넌트 내에서 함수를 생성하고 있다면 (프로그래밍 구동에는 문제가 없겠지만) 새로운 함수 참조 값을 계속해서 만들고 있는 것, 다시 말해 똑같은 모양의 함수를 계속해서 만들어 메모리에 계속해서 할당하고 있다는 것을 뜻한다.

의존성에 포함된 값이 변경되지 않는다면 이전에 생성한 함수 참조 값을 반환해주는 것이 useCallback이다.

어떻게 사용할까?

const onChange = useCallback(e => {
    setNumber(e.target.value);
}, []); // 컴포넌트가 처음 렌더링될 때만 함수 생성

const onInsert = useCallback(() => {
    const nextList = list.concat(parseInt(number));
    setList(nextList);
    setNumber(“);
  }, [number, list]); // number 혹은 list가 바뀌었을 때만 함수 생성

함수 내부에서 상태 값에 의존해야 할 때는 그 값을 반드시 두 번째 파라미터 안에 포함시켜 주어야 합니다. 예를 들어 onChange의 경우 기존의 값을 조회하지 않고 바로 설정만 하기 때문에 배열이 비어 있어도 상관없지만, onInsert는 기존의 number와 list를 조회해서 nextList를 생성하기 때문에 배열 안에 number와 list를 꼭 넣어 주어야 합니다.

인라인 콜백과 그것의 의존성 값의 배열을 전달하세요. useCallback은 콜백의 메모이제이션된 버전을 반환할 것이다. 그 메모이제이션된 버전은 콜백의 의존성이 변경되었을 때에만 변경된다. 이것은, 불필요한 렌더링을 방지하기 위해 (예로 shouldComponentUpdate를 사용하여) 참조의 동일성에 의존적인 최적화된 자식 컴포넌트에 콜백을 전달할 때 유용하다.

자식컴포넌트에 함수를 넘길 때 무조건 useCallback를 적용시켜줘야 한다. 자식 입장에서는 부모가 매번 새로운 함수를 주는 것이라고 판단한다고 한다.

useEffect에서 제2의 인자로 의존성 배열 안에 값이 존재할 경우 => componentDidUpdate
useEffect에서 제2의 인자로 의존성 배열로 빈 배열로 존재할 경우 => componentDidMount
: 위의 useEffect 와 useCallback이 동작하는 방식이 유사하다.

useRef

1) dom 접근

const inputEl = useRef(null);
inputEl.current.focus();

2) 값 저장

렌더링과 관련되지 않은 값을 저장할때 사용한다
ref 안의 값이 바뀌어도 컴포넌트가 렌더링되지 않는다

0개의 댓글