본문 바로가기
▼ 코딩 공부하기/▼▼ 프론트엔드

💻 React 컴포넌트 차이와 성능 최적화 Hook 정복 (feat. 왕초보 위클리 페이퍼 #6)

by mdeeno 2026. 1. 3.
반응형

안녕하세요! 개발자 꿈나무 엠디노입니다.
현재 '웹개발 풀스택' 과정을 훈련하고 있습니다.

 

이번 주차 위클리 페이퍼 주제는 리액트(React)를 구성하는 핵심 단위인 컴포넌트와,
성능 최적화의 열쇠인 useMemo, useCallback입니다.

"컴포넌트는 그냥 함수인가요, 객체인가요?"
"성능 좋게 하려고 쓴 Hook인데 왜 더 느려진 것 같죠?"

 

저와 같은 고민을 하시는 분들을 위해, 이번에도 7살 아이에게 설명하듯 아주 쉬운 비유와 코드로 정리해 보았습니다.


이전 포스팅 글은 아래 글을 참고해주세요!

💻 React 렌더링 방식과 Virtual DOM 개념 정복 feat 왕초보 위클리 페이퍼5

 


⭐️ 위클리 페이퍼 주제

  • React 컴포넌트의 정의 및 클래스형 vs 함수형 차이
  • useMemo와 useCallback의 활용 및 남용 시 문제점

1. React 컴포넌트(Component)란 무엇일까?

리액트에서 컴포넌트는 화면을 구성하는 '작은 부품'입니다. 마치 레고 블록처럼요.

🐣 7살 버전: 레고 성 만들기
우리가 아주 큰 레고 성을 만든다고 해봐요. 성을 통째로 한 번에 만들기는 너무 힘들죠?

그래서 우리는 '성벽 블록', '창문 블록', '지붕 블록'을 따로따로 만든 다음에 하나로 합쳐서 성을 완성해요.

여기서 각각의 블록들이 바로 컴포넌트예요!

창문이 깨지면 성 전체를 부술 필요 없이 '창문 블록'만 새로 갈아 끼우면 되니까 정말 편하겠죠?

💻 클래스형 vs 함수형 (과거의 형님 vs 요즘 대세)

예전에는 클래스(Class)라는 방식으로 컴포넌트를 만들었지만, 지금은 함수(Function) 방식을 주로 사용합니다.

구분 클래스형 컴포넌트 함수형 컴포넌트 (요즘 방식)
선언 방식 class 키워드 사용 function 또는 화살표 함수 사용
상태 관리 this.state와 setState useState Hook 사용
추세 예전 코드 유지보수 시 주로 사용 리액트 공식 추천 방식 (Hook 사용)

2. useMemo와 useCallback: "기억력 천재 리액트"

리액트는 화면이 바뀔 때마다 코드를 처음부터 끝까지 다시 읽어요(재렌더링). 이때 너무 복잡한 계산을 매번 하면 리액트도 지쳐버리겠죠? 그때 사용하는 것이 바로 메모이제이션(기억하기) 도구입니다.

🐣 7살 버전: 똑똑한 암기 대장
- useMemo (계산 결과 기억하기): 선생님이 "12345 곱하기 6789는 뭐야?"라고 물어보셨어요. 힘들게 계산해서 답을 맞혔는데, 잠시 후에 또 똑같은 문제를 물어보시면 어떡하죠? 다시 계산하는 대신 포스트잇에 적어둔 '답'을 보고 바로 말하는 게 useMemo예요.

- useCallback (행동 기억하기): 이번에는 선생님이 "박수 두 번 치고 윙크해!"라는 '심부름(함수)'을 시켰어요. 매번 심부름 내용을 새로 받아적는 대신, 머릿속에 그 행동 자체를 딱 외워두고 필요할 때마다 그대로 하는 게 useCallback이에요.


3. 남용할 경우 발생할 수 있는 문제점

"어? 그러면 모든 걸 다 기억해두면 무조건 좋은 거 아닌가요?"

아니요!

 

🐣 7살 버전: 너무 많은 포스트잇
기억해야 할 게 너무 많아서 온 집안에 포스트잇을 수만 장 붙여놨다고 생각해보세요.

오히려 내가 원하는 답을 찾는 데 시간이 더 오래 걸리고, 집도 엉망이 되겠죠?

  • 메모리 낭비: 값을 기억하려면 별도의 메모리 공간이 필요합니다.
  • 오히려 느려짐: 리액트가 "이걸 기억해야 하나? 예전이랑 똑같나?"라고 비교하는 과정 자체가 비용입니다. 아주 간단한 작업은 그냥 매번 새로 계산하는 게 더 빠릅니다!

💻 코드로 보는 최적화 예시

상태가 바뀔 때 어떤 부분을 기억할지 결정하는 실제 코드 구조입니다.

import React, { useState, useMemo, useCallback } from 'react';

function Calculator() {
  const [count, setCount] = useState(0);
  const [inputValue, setInputValue] = useState("");

  // [수정사항] 1. 복잡한 계산 결과값 기억 (useMemo)
  // inputValue가 바뀔 때만 실행되고, count가 바뀔 때는 재사용됩니다.
  const expensiveResult = useMemo(() => {
    console.log("복잡한 계산 중...");
    return inputValue.length * 1000; 
  }, [inputValue]);

  // [수정사항] 2. 함수 자체를 기억 (useCallback)
  const handleClick = useCallback(() => {
    setCount((prev) => prev + 1);
  }, []);

  return (
    <div>
      <h2>숫자: {count}</h2>
      <button onClick={handleClick}>1 더하기</button>
      <input 
        value={inputValue} 
        onChange={(e) => setInputValue(e.target.value)} 
      />
      <p>결과: {expensiveResult}</p>
    </div>
  );
}

🔥 최종 요약 및 실무 팁

1. 컴포넌트는 재사용 가능한 화면의 부품이다. (함수형이 대세!)
2. useMemo는 '값'을, useCallback은 '함수'를 기억한다.
3. 성능 최적화는 공짜가 아니다: 진짜로 무거운 작업일 때만 사용하자!

 

 

이상 개발자 꿈나무 엠디노였습니다...
머지않아 또 다른 숙제와 문제 해결 과정으로 찾아뵙겠습니다..
그럼 이만!

반응형