React

React useMemo & useRef – 렌더링 최적화와 값 유지의 모든 것

jonbeo 2025. 8. 19. 10:46
반응형

 

 

안녕하세요 😊
React를 사용하다 보면
“이 계산은 매번 다시 하지 않아도 되는데…”
“렌더링이 되어도 이 값은 유지하고 싶다…”
이럴 때 유용한 Hook이 바로 **useMemo**와 **useRef**입니다.

이번 글에서는 두 Hook의 차이점과
실무에서 어떻게 활용할 수 있는지 예제와 함께 정리해드리겠습니다.


📍 1. useMemo – 계산 결과 메모이제이션

기본 개념

의존성 배열이 변할 때만 함수를 실행하고, 그 외에는 이전 계산값을 재사용

 

예제

import { useMemo, useState } from "react";

export default function ProductList({ products }) {
  const [filter, setFilter] = useState("");

  const filtered = useMemo(() => {
    console.log("필터링 계산 실행");
    return products.filter((p) =>
      p.name.toLowerCase().includes(filter.toLowerCase())
    );
  }, [products, filter]);

  return (
    <>
      <input value={filter} onChange={(e) => setFilter(e.target.value)} />
      <ul>{filtered.map((p) => <li key={p.id}>{p.name}</li>)}</ul>
    </>
  );
}

 

✅ 매번 필터 계산하지 않고, productsfilter가 변할 때만 재계산
✅ 무거운 연산, 데이터 가공 등에 적합


📍 2. useRef – 값 또는 DOM 참조 유지

기본 개념

컴포넌트가 리렌더링되어도 유지되는 mutable 객체를 반환

 

예제

import { useRef } from "react";

export default function Timer() {
  const timerId = useRef(null);

  const start = () => {
    timerId.current = setInterval(() => {
      console.log("타이머 동작중...");
    }, 1000);
  };

  const stop = () => {
    clearInterval(timerId.current);
  };

  return (
    <>
      <button onClick={start}>시작</button>
      <button onClick={stop}>정지</button>
    </>
  );
}

 

✅ 리렌더링해도 timerId 값 유지
✅ DOM 요소 직접 제어에도 활용

const inputRef = useRef();
<input ref={inputRef} />;
inputRef.current.focus();

 


📍 3. useMemo vs useRef 차이

구분 useMemo useRef
목적 계산 결과 캐싱 값/DOM 참조 유지
재계산 시점 의존성 변경 시 직접 변경해야 함
주요 용도 성능 최적화, 무거운 연산 DOM 제어, 렌더 간 값 유지
반환 값 계산 결과 { current: ... } 객체
 

📍 4. 실무 활용 팁

useMemo

  • 리스트 필터링, 정렬, 데이터 변환에 사용
  • 무거운 연산에만 적용 (모든 계산에 쓰면 오히려 성능 저하)
  • 의존성 배열 정확히 관리

useRef

  • setTimeout, setInterval ID 저장
  • 이전 상태 저장 (이전 값 비교)
  • 비제어 컴포넌트 값 관리
  • Canvas, Video, Audio 등 DOM API 제어

✅ 마무리

useMemo계산 결과 재사용,
useRef값이나 DOM 참조 유지에 최적화된 Hook입니다.
이 두 가지를 잘 활용하면 불필요한 렌더링을 줄이고,
UI의 반응성을 높일 수 있습니다. 😊

반응형