useMemo()
useMemo()
리액트에서 컴포넌트가 리렌더링 될 때 변화가 없는 부분도 리렌더링 된다면 자원이 낭비되고 성능에도 문제가 생기게 됨
이러한 상황에서 useMemo를 사용하면 의존성 배열의 값에 아무런 변화가 없다면 이전에 연산된 값인 memorized value를 리턴하고 불필요한 연산을 없애 성능을 최적화할 수 있음
동일한 입력이 들어오면 재활용하는 프로그래밍 기법
■ 동작 순서
렌더링 → 컴포넌트 함수 호출 → Memoize된 함수 재사용
■ 문법
1
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- 첫번째 인자 : 콜백 함수
- 두번째 인자 : 의존성 배열
만약 빈배열을 넘겨주면 맨 처음 컴포넌트가 마운트 되었을 때만 값을 계산하고, 이후에는 항상 memoization된 값을 꺼내와서 사용함
■ 예시
● 기능
- + , - 버튼을 누르면 number 값이 변함
- input에 값을 입력하면 text 값이 변함
● 문제점
“숫자”가 변경되었을때는 “숫자가 변동되었습니다”만,
“글자”가 변경되었을때는 “글자가 변동되었습니다”만
출력되어야하는데, 숫자를 변경하거나 글자를 변경했을 경우 두가지 모두 출력됨 (불필요한 자원이 낭비됨)
● useMemo()를 사용해서 불필요한 재렌더링 막기
showNumber은 number가 변경되었을 때만 실행되도록,
showText는 text가 변경되었을 때만 실행되도록 작성
1
2
const showNumber = useMemo(() => getNumber(number), [number]);
const showText = useMemo(() => getText(text), [text]);
● 전체 코드
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.