Post

useMemo()

useMemo()

리액트에서 컴포넌트가 리렌더링 될 때 변화가 없는 부분도 리렌더링 된다면 자원이 낭비되고 성능에도 문제가 생기게 됨

이러한 상황에서 useMemo를 사용하면 의존성 배열의 값에 아무런 변화가 없다면 이전에 연산된 값인 memorized value를 리턴하고 불필요한 연산을 없애 성능을 최적화할 수 있음

동일한 입력이 들어오면 재활용하는 프로그래밍 기법

■ 동작 순서

렌더링 → 컴포넌트 함수 호출 → Memoize된 함수 재사용

■ 문법

1
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • 첫번째 인자 : 콜백 함수
  • 두번째 인자 : 의존성 배열

만약 빈배열을 넘겨주면 맨 처음 컴포넌트가 마운트 되었을 때만 값을 계산하고, 이후에는 항상 memoization된 값을 꺼내와서 사용함

■ 예시

https://camo.githubusercontent.com/a04cc04083aac9768d2a82f4e7fc944829414f474aea9cfacccee5423d2bb116/68747470733a2f2f696d67312e6461756d63646e2e6e65742f7468756d622f523132383078302f3f73636f64653d6d746973746f72793226666e616d653d68747470732533412532462532466b2e6b616b616f63646e2e6e6574253246646e25324647484630582532466274725049527a493130352532466f65724f4341394f384b443541546f4e416c64665931253246696d672e706e67

● 기능

  1. + , - 버튼을 누르면 number 값이 변함
  2. input에 값을 입력하면 text 값이 변함

● 문제점

“숫자”가 변경되었을때는 “숫자가 변동되었습니다”만,
“글자”가 변경되었을때는 “글자가 변동되었습니다”만
출력되어야하는데, 숫자를 변경하거나 글자를 변경했을 경우 두가지 모두 출력됨 (불필요한 자원이 낭비됨)

● useMemo()를 사용해서 불필요한 재렌더링 막기

showNumber은 number가 변경되었을 때만 실행되도록,
showText는 text가 변경되었을 때만 실행되도록 작성

1
2
const showNumber = useMemo(() => getNumber(number), [number]);
const showText = useMemo(() => getText(text), [text]);

https://camo.githubusercontent.com/6ae8af4453e99fd32dc1060dc64ccc727405d339b8c7fc7de02aade185d339fe/68747470733a2f2f696d67312e6461756d63646e2e6e65742f7468756d622f523132383078302f3f73636f64653d6d746973746f72793226666e616d653d68747470732533412532462532466b2e6b616b616f63646e2e6e6574253246646e25324662763364794125324662747250494a6f6f5868612532467562376d4572784559437939386e735849726a34344b253246696d672e706e67

● 전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Appmemo.js
const { useState } = require("react");
const { default: ShowState } = require("./ShowState");

function AppMemo() {
  const [number, setNumber] = useState(0);
  const [text, setText] = useState("");

  const increaseNum = () => {
    setNumber((prevState) => prevState + 1);
  };
  const decreaseNum = () => {
    setNumber((prevState) => prevState - 1);
  };

  const onChange = (e) => {
    setText(e.target.value);
  };

  return (
    <div>
      <button onClick={increaseNum}>+</button>
      <button onClick={decreaseNum}>-</button>
      <input type="text" placeholder="Text" onChange={onChange} />
      <ShowState number={number} text={text} />
    </div>
  );
}

export default AppMemo;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// ShowState

import React, { useMemo } from "react";

const getNumber = (number) => {
  console.log("숫자가 변동되었습니다.");
  return number;
};

const getText = (text) => {
  console.log("글자가 변동되었습니다.");
  return text;
};

const ShowState = ({ number, text }) => {
  const showNumber = useMemo(() => getNumber(number), [number]);
  const showText = useMemo(() => getText(text), [text]);

  return (
    <div className="info-wrapper">
      {showNumber} <br />
      {showText}
    </div>
  );
};

export default ShowState;
This post is licensed under CC BY 4.0 by the author.