useMemo 훅은 함수 컴포넌트 내부에서 발생하는 연산을 최적화 하기 위해서 사용되는 로직입니다.
해당 Hook 이 실제로 어떻게 작동이 되는지 확인하기 위해서
실제 코드를 작성하여 확인해 보겠습니다.
우선은 위와 같은 코드를 만들었습니다.
아직은 useMemo 과 활용되지 않은 코드입니다.
Input 창에 숫자를 넣고 추가 버튼을 누르면 리스트 내부로 숫자가 들어가고,
해당 숫자들을 가지고 평균값을 출력하는 간단한 코드입니다.
import { useState } from "react";
const getAverage = (numbers) => {
console.log("Calcuating Average...");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = (e) => {
setNumber(e.target.value);
};
const onInsert = (e) => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
};
return (
{list.map((value, index) => {
- {value}
;
})}
평균값 : {getAverage(list)}
);
};
export default Average;
실행되는 화면을 한 번 보겠습니다.
Input 창에 숫자를 적을 때마다, Console 창에 Average 를 계산중이라는 메시자가 발생합니다.
이 메시지는 분명 getAverage 라는 함수 내부에 정의를 했죠?
그리고 이 getAverage 는 버튼을 눌렀을 때만 작동되도록 했는데, Input 창에 변화를 줘도 계속해서 나타납니다.
변화가 있을 때마다 DOM 을 랜더링 하는 리액트 특성 때문인데요.
아무 상관도 없는 변화 때문에 다시 한 번 모든 DOM을 랜더링 하는 것은 비효율적이니 변환을 해봅시다.
import { useState, useMemo } from "react";
const getAverage = (numbers) => {
console.log("Calcuating Average...");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = (e) => {
setNumber(e.target.value);
};
const onInsert = (e) => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
};
//해당 부분을 추가한다.
const avg = useMemo(() => getAverage(list), [list]);
return (
{list.map((value, index) => {
return - {value}
;
})}
평균값 : {avg}
);
};
export default Average;
기존에 곧장 getAverage(list) 를 사용하여 평균값을 보여주던 부분에 새로운 변수인 avg 를 할당합니다.
이 avg 에는 useMemo 훅을 사용해줍니다.
getAverage(list) 사용은 그대로 해주되, [list] 를 추가하여 해당 변수에 변화가 생겼을 때에만 랜더링이 일어나도록 변형을 주었습니다.
결과적으로 리스트에 추가라는 버튼을 눌러 list 내부에 변화가 생겼을 때에만
getAverage 가 실행되는 것을 알 수 있습니다.
조금 더 최적화 가능한 기법을 위해 다음 버튼을 눌러주세요.