최적화를 위한 memo, useMemo, useCallback

togongs·2022년 10월 5일
0

2022

목록 보기
14/19

memo / useMemo / useCallback?

  • 렌더링 이후의 값과 전의 값을 비교해서 같으면 재생성하지말라고 하는것
    반드시 렌더링이 필요한곳에 사용하고 무분별한 사용은 금지

React.memo (컴포넌트)

  • 메모이제이션 된 컴포넌트를 반환 (고차 컴포넌트)
  • 부모 컴포넌트가 렌더링되면 자식 컴포넌트는 같이 렌더링 되는게 원칙이지만, memo를 사용하여 자식컴포넌트가 부모컴포넌트의 마지막으로 렌더링된 결과를 기억하여 부모컴포넌트의 prop이 같다면 리렌더링 되지않고 부모컴포넌트의 prop이 변할때만 렌더링이 되게 한다
  • 즉, 부모컴포넌트에서 useState 훅을 사용했을때, 자식컴포넌트에 React.memo를 감싸주면 state값이 그대로면 리렌더링 되지않고 state값이 변하면 리렌더링 된다.
  • https://ko.reactjs.org/docs/react-api.html#reactmemo

useMemo 변수(객체,배열)을 재사용

  • 메모이제이션 된 연산 값(함수 실행의 결과)을 반환
  • 의존성[]이 변경되었을 때만 다시 실행되어 값을 return
  • props를 받아 컴포넌트를 리렌더링하지 않고
    마지막으로 렌더링된 결과를 재사용
  • 특정한 값을 return 하여 memoriztion (함수도 값으로 인지 가능)
import React from "react";

function CommentIem({ title, content, likes }) {
  
  const rate = React.useMemo(() => {
    return likes > 10 ? "Good" : "Bad";
  }, [likes]);
  
  return (
    <div>
      <span>{likes}</span>
      <br />
      <span>{rate}</span>
    // likes가 10보다 크면 Good, 작으면 Bad 표시
    </div>
  );
}

export default CommentIem;

useCallback 함수를 재사용

  • 메모이제이션 된 함수를 반환
  • 리렌더링 시, 렌더링 전 최신 state 유지
  • 컴포넌트가 리렌더링될 때마다 함수를 새로 만들지 않고 한번 함수를 만들고 재사용
  • 함수안에서 사용하는 state, 함수등의 props가 있다면, 꼭 의존성[]에 넣어줘야한다. 이 값을 넣어야 가장 최신값을 참조
  • 의존성이 변경되었을 때만 새롭게 생성되어 참조값이 변경
const onChange = useCallback((e) => {
  setValue(e.target.value);
}, [])

const onSubmit = useCallback(
  (e) => {
    onInsert(value);
    setValue(''); //value 값 초기화
    e.preventDefault();
  },
  [onInsert, value],
);
  
<form className="TodoInsert" onSubmit={onSubmit}>
  <input
    placeholder=" 할 일을 입력하세요"
    value={value}
    onChange={onChange}
 	<button type="submit">생성</button>
 </form>
/>

// handleChange 함수도 계속 생성된다.
// 이럴때 useCallback을 사용하여 처음 생성될때만 함수를 불러오고 다시 함수를 부르지 않는다

memo와 useCallback을 함께 쓰자

  • memo를 썼지만 state가 계속 변한다면 부모컴포넌트의 함수에 useCallback도 함께 써줘야한다.
    부모컴포넌트의 다른 state가 변할때 useCallback으로 이전값을 기억해두지 않으면 함수가 다시 실행되면서 자식컴포넌트가 리렌더링되기 때문이다.

무조건 쓰는게 좋을까?

  • 리액트에서 5번 렌더링 되는걸 4번, 3번으로 줄인다고 유의미한 성능향상을 가져오지는 않는다.
    useMemo나 useCallback도 부가적인 연산이 필요하기 때문에 남용하게 된다면 오히려 예상치 못한 성능저하?를 가져올 수 있다.
    따라서 성능 최적화를 위하여 사용되어야하지 렌더링을 방지하기 위해 사용하면 안된다
profile
개발기록

0개의 댓글