
React에서 성능 최적화를 위해 불필요한 리렌더링을 줄이는 함수가 존재하는데, 리렌더링을 줄이기 위해 사용하는 대표적인 최적화 함수 3가지가 있다.
useMemo() → 함수 호출 결과를 저장useCallback() → 함수를 저장memo() → 컴포넌트를 저장React의 함수형 컴포넌트는 함수 자체
따라서 컴포넌트가 리렌더링될 때마다 함수 내부의 모든 변수가 다시 선언
이 과정에서 재사용 가능한 함수조차도 새로 만들어지는 비효율적인 동작이 발생하는 문제
useMemo() : 같은 연산을 계속 반복하는 것 방지 useCallback() : 같은 함수를 계속 생성하는 것 방지memo() : 같은 컴포넌트를 계속 렌더링하는 것 방지 useMemo() - 함수 결과를 저장useMemo()는 함수의 실행 결과를 저장하여, 값이 변경되지 않으면 다시 호출하지 않음
import { useState } from 'react';
function App() {
const [number, setNumber] = useState(0);
const [rerender, setRerender] = useState(false);
const plus1 = (num) => {
console.log('plus1 실행됨');
return num + 1;
};
const numberPlus1 = plus1(number);
return (
<>
<div>numberPlus1: {numberPlus1}</div>
<button onClick={() => setNumber(number + 1)}>number + 1</button>
<button onClick={() => setRerender(!rerender)}>Rerender</button>
</>
);
}
export default App;

✅ 문제: rerender 버튼을 눌러도 plus1()이 불필요하게 실행됨
useMemo() 사용import { useState, useMemo } from 'react';
function App() {
const [number, setNumber] = useState(0);
const [rerender, setRerender] = useState(false);
const plus1 = (num) => {
console.log('💡 plus1 실행됨');
return num + 1;
};
const numberPlus1 = useMemo(() => plus1(number), [number]);
return (
<>
<div>numberPlus1: {numberPlus1}</div>
<button onClick={() => setNumber(number + 1)}>number + 1</button>
<button onClick={() => setRerender(!rerender)}>Rerender</button>
</>
);
}
export default App;

✅ 최적화 효과: number 값이 변할 때만 plus1()이 실행됨 → 불필요한 연산 방지
useCallback() - 함수를 저장useCallback()은 함수 자체를 저장하여, 컴포넌트가 리렌더링될 때 함수를 새로 생성하는 것을 방지
import { useState } from 'react';
function App() {
const [number, setNumber] = useState(0);
const plus1 = (num) => {
console.log('💫 plus1 실행됨');
return num + 1;
};
return (
<>
<button onClick={() => setNumber(plus1(number))}>number + 1</button>
</>
);
}
export default App;

✅ 문제: plus1() 함수가 매번 새롭게 생성됨
useCallback() 사용**import { useState, useCallback } from 'react';
function App() {
const [number, setNumber] = useState(0);
const plus1 = useCallback((num) => {
console.log('💡 plus1 실행됨');
return num + 1;
}, []);
return (
<>
<button onClick={() => setNumber(plus1(number))}>number + 1</button>
</>
);
}
export default App;

✅ 최적화 효과: plus1() 함수가 한 번만 생성되고, 이후 재사용됨
memo() - 컴포넌트 저장memo()는 동일한 props가 전달될 경우, 컴포넌트가 다시 렌더링되지 않도록 함.
즉, 불필요한 렌더링을 방지할 때 사용
import { useState } from "react";
function App() {
const [number, setNumber] = useState(0);
return (
<>
<NumberDisplay number={number} />
<button onClick={() => setNumber(number + 1)}>number + 1</button>
</>
);
}
const NumberDisplay = ({ number }) => {
console.log("🖥️ Display 렌더링");
return <div>number: {number}</div>;
};
export default App;

✅ 문제: number 값이 변할 때마다 NumberDisplay가 계속 리렌더링됨
memo() 사용**import { useState, memo } from "react";
function App() {
const [number, setNumber] = useState(0);
return (
<>
<NumberDisplay number={number} />
<button onClick={() => setNumber(number + 1)}>number + 1</button>
</>
);
}
const NumberDisplay = memo(({ number }) => {
console.log("🖥️ Display 렌더링");
return <div>number: {number}</div>;
});
export default App;

✅ 최적화 효과: number 값이 변하지 않으면 NumberDisplay가 렌더링되지 않음

React Developer Tools
이 확장 프로그램을 사용하면 불필요한 리렌더링을 감지
"Highlight updates when components render" 옵션을 켜면 렌더링된 컴포넌트가 강조 표시됨.