본문 바로가기
일상이 개발

React 고급 Hook 완전정복|useRef, useMemo, useCallback 실전 사용법 & 최적화 전략

by 아빠고미 2025. 7. 8.
반응형

📘 리액트 스터디 시리즈 10편

고급 Hook 완전정복|useRef, useMemo, useCallback의 모든 것

이제 리액트도 어느 정도 익숙해지셨죠? 👨‍💻 이번 편에서는 고급 Hook 3총사 – useRef, useMemo, useCallback에 대해 배워봅니다.

렌더링 최적화, DOM 직접 접근, 계산 결과 캐싱 등 실전에서 성능과 효율을 챙기려면 꼭 필요한 친구들입니다! 🔧


🔍 1. useRef – DOM에 직접 접근하기

useRef는 DOM 요소에 직접 접근하거나, 렌더링과 무관한 값을 저장할 때 사용합니다.

import { useRef } from 'react';

function InputFocus() {
  const inputRef = useRef(null);

  const handleClick = () => {
    inputRef.current.focus();
  };

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>포커스 주기</button>
    </>
  );
}

📌 ref는 DOM 노드를 직접 제어할 때 매우 유용합니다.


🧠 2. useMemo – 계산 결과 기억하기

컴포넌트가 리렌더링될 때마다 비용이 큰 계산을 다시 하지 않도록 useMemo를 사용하면 메모이제이션(캐싱)이 가능합니다.

import { useMemo, useState } from 'react';

function ExpensiveCalc({ number }) {
  const slowResult = useMemo(() => {
    console.log('🚨 느린 계산 시작');
    let result = 0;
    for (let i = 0; i < 1000000000; i++) {
      result += number;
    }
    return result;
  }, [number]);

  return <p>계산 결과: {slowResult}</p>;
}

📌 의존 배열 [number]가 바뀔 때만 다시 계산됩니다.


🔁 3. useCallback – 함수 재생성 막기

자식 컴포넌트에 함수를 props로 넘길 때, 불필요한 재생성을 막기 위해 useCallback을 사용합니다.

import { useCallback, useState } from 'react';

function Parent() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount((prev) => prev + 1);
  }, []);

  return <Child onClick={handleClick} />;
}

function Child({ onClick }) {
  console.log('🔄 Child 렌더링');
  return <button onClick={onClick}>클릭</button>;
}

📌 불필요한 렌더링 최적화에 매우 유용합니다.


🧪 종합 예제 - 고급 Hook 함께 사용하기

function Example() {
  const inputRef = useRef();
  const [value, setValue] = useState('');

  const handleSubmit = useCallback(() => {
    alert(`입력값: ${value}`);
    inputRef.current.focus();
  }, [value]);

  const charCount = useMemo(() => {
    console.log('⏳ 문자 수 계산');
    return value.length;
  }, [value]);

  return (
    <div>
      <input
        ref={inputRef}
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      <p>문자 수: {charCount}</p>
      <button onClick={handleSubmit}>제출</button>
    </div>
  );
}

🧠 정리 – 오늘 배운 고급 Hook 핵심

  • ✔️ useRef: DOM에 직접 접근하거나 값 저장
  • ✔️ useMemo: 계산 결과 캐싱 (렌더링 최적화)
  • ✔️ useCallback: 함수를 메모이제이션하여 재생성 방지

📌 다음 편 예고

11편에서는 리액트 앱의 에러 처리와 에러 바운더리를 배웁니다!

실전 서비스에서 꼭 필요한 예외 처리 기술을 정리해드릴게요 🚨


💬 오늘 내용은 살짝 어려울 수 있지만, 직접 써보면 분명 내 것이 됩니다! 질문이나 피드백은 언제든 환영합니다 😊

반응형