React 최적화 함수

코딩로그·2025년 2월 27일

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 컴포넌트 확인이 가능한 웹브라우저 확장 프로그램

React Developer Tools
이 확장 프로그램을 사용하면 불필요한 리렌더링을 감지

  • "Highlight updates when components render" 옵션을 켜면 렌더링된 컴포넌트가 강조 표시됨.

profile
hello world!

0개의 댓글