1일 1CS(Computer Science)

useRef는 언제 사용하나요?

표자 2025. 6. 19. 09:57

useRef가 뭔가요? 🤔

useRef는 React의 훅 중 하나로, 값을 저장하는 상자 같은 역할을 해요!

하지만 useState와는 다르게 값이 바뀌어도 컴포넌트가 다시 렌더링되지 않아요 🎪

마치 메모장과 화이트보드의 차이라고 생각하면 돼요

  • useState = 화이트보드 📋: 내용이 바뀌면 모든 사람이 봐야 함 (리렌더링)
  • useRef = 개인 메모장 📝: 내용이 바뀌어도 다른 사람은 몰라도 됨 (리렌더링 없음)

 

useRef 사용 시나리오 2가지 🎭

1. DOM 요소에 접근할 때 👆

실생활 예시: 로그인 페이지에서 아이디 입력창에 자동으로 커서가 깜빡이게 하고 싶을 때!

const LoginPage = () => {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus(); // 페이지 로드되면 자동 포커스!
  }, []);

  return <input ref={inputRef} placeholder="아이디를 입력하세요" />;
};

다른 활용 예시들

  • 스크롤 위치 조작하기📜
  • 비디오 재생/정지 제어하기🎬
  • 캔버스 그리기🎨
  • 모달 외부 클릭 감지하기🪟

2. 리렌더링 없이 값 저장할 때 💾

실생활 예시: 스톱워치 만들 때 타이머 ID를 저장해야 하는데, 이게 바뀔 때마다 화면이 깜빡이면 안 되잖아요!

const Stopwatch = () => {
  const [time, setTime] = useState(0);
  const timerRef = useRef(null);

  const start = () => {
    timerRef.current = setInterval(() => {
      setTime(prev => prev + 1);
    }, 1000);
  };

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

  return (
    <div>
      <p>시간: {time}초</p>
      <button onClick={start}>시작</button>
      <button onClick={stop}>정지</button>
    </div>
  );
};

 

언제 useRef를 써야 할까? 🤷‍♂️

✅ useRef를 사용하는 경우

  • DOM 조작이 필요할 때 (포커스, 스크롤 등)
  • 타이머 ID, 인터벌 ID 저장할 때
  • 이전 값을 기억해야 할 때
  • 렌더링과 무관한 값을 저장할 때

❌ useRef를 사용하지 않는 경우

  • 화면에 보여질 데이터를 저장할 때 → useState 사용
  • 사용자 입력값을 받을 때 → useState 사용
  • API 응답 데이터를 저장할 때 → useState 사용

useState vs useRef 비교 ⚡

값 변경 시 리렌더링 ✅ 함 ❌ 안 함
초기값 설정 useState(0) useRef(0)
값 접근 방법 value ref.current
주 사용 목적 화면 데이터 DOM 접근/값 저장

실무에서 자주 사용하는 패턴 🔥

1. 이전 값 추적하기

const usePrevious = (value) => {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
};

2. 컴포넌트 마운트 여부 확인

const isMounted = useRef(false);

useEffect(() => {
  isMounted.current = true;
  return () => {
    isMounted.current = false;
  };
}, []);

3. 디바운스 구현

const debounceRef = useRef(null);

const handleSearch = (query) => {
  clearTimeout(debounceRef.current);
  debounceRef.current = setTimeout(() => {
    // 실제 검색 로직
  }, 300);
};

 

주의사항 ⚠️

1. ref.current는 변경 가능해요!

// 이건 괜찮아요
ref.current = "새로운 값";

// 하지만 렌더링 중에는 하지 마세요!
// 렌더 함수 안에서 ref.current = "값" ❌

2. 초기 렌더링에서는 null일 수 있어요

const myRef = useRef(null);

// 처음에는 null이므로 체크 필요!
if (myRef.current) {
  myRef.current.focus();
}

 

Next.js에서 useRef 활용하기 🚀

SSR 환경에서 주의점: 서버에서는 DOM이 없으므로 useEffect 안에서 DOM 조작을 해야 해요!

// ✅ 올바른 방법
useEffect(() => {
  if (typeof window !== 'undefined') {
    inputRef.current?.focus();
  }
}, []);

성능 최적화 팁 ⚡

useRef는 렌더링을 트리거하지 않으므로, 무거운 계산 결과나 캐시 데이터를 저장할 때 유용해요!

const expensiveCalculationRef = useRef(null);

const getResult = () => {
  if (!expensiveCalculationRef.current) {
    expensiveCalculationRef.current = heavyCalculation();
  }
  return expensiveCalculationRef.current;
};

면접 답변 💼

"useRef는 언제 사용하나요?"

useRef는 두 가지 주요 용도로 사용됩니다. 첫째, DOM 요소에 직접 접근해야 할 때 사용하며, 포커스 설정이나 스크롤 조작 등이 대표적입니다. 둘째, 렌더링을 트리거하지 않으면서 값을 저장해야 할 때 사용하며, 타이머 ID나 이전 값 추적 등에 활용됩니다. useState와 달리 useRef는 값이 변경되어도 컴포넌트가 리렌더링되지 않는 것이 핵심 차이점입니다.

 


 

useRef는 언제 사용하나요?

프론트엔드와 관련된 질문이에요.

useRef()는 React의 훅 중 하나로, 컴포넌트 내에서 변경 가능한 값을 저장하고 관리할 수 있게 해줍니다. useRef()는 주로 두 가지 목적에 사용됩니다. DOM 요소에 접근하거나, 값을 유지하면서도 렌더링을 트리거하지 않기 위해 사용됩니다.

첫째, useRef()는 DOM 요소에 접근할 때 사용됩니다. 예를 들어, 특정 DOM 요소에 직접 접근하고 싶을 때 useRef()를 사용하여 해당 요소의 참조를 얻을 수 있습니다. 이는 useEffect()나 이벤트 핸들러 내에서 해당 DOM 요소에 직접 작업을 수행할 때 유용합니다. 예를 들어, 입력 필드에 포커스를 설정하고 싶을 때, useRef()를 사용해 input 요소에 접근할 수 있습니다.

const inputRef = useRef(null);

useEffect(() => {
  inputRef.current.focus(); // 컴포넌트 마운트 시 input에 포커스를 맞춘다.
}, []);

return <input ref={inputRef} />;

둘째, useRef는 값을 유지하면서도 렌더링을 트리거하지 않기 위해 사용됩니다. 일반적으로 상태 값을 관리할 때 사용하는 useState()는 상태 변화가 리렌더링을 트리거하는 반면, useRef()는 값이 변경되어도 리렌더링을 트리거하지 않습니다. 예를 들어, 타이머 id를 추적할 때 useRef()를 사용할 수 있습니다.

const timerRef = useRef(null);

const startTimer = () => {
  timerRef.current = setInterval(() => {
    console.log('타이머 실행')
  }, 1000);
};

const stopTimer = () => {
  clearInterval(timerRef.current); // 타이머를 정지한다.
};

위 예시에서 useRef()를 이용하여 타이머의 id를 추적하면서도 해당 상태 값이 업데이트될 때 컴포넌트를 리렌더링하지 않습니다.

728x90