본문 바로가기
React

[React] useRef 훅 사용법

by goblin- 2024. 9. 13.

**useRef**는 리액트에서 제공하는 훅 중 하나로, 주로 DOM 요소에 접근하거나 값을 기억하고 추적하는 용도로 사용됩니다. **useRef**는 클래스형 컴포넌트에서 사용하던 **createRef**와 유사한 기능을 함수형 컴포넌트에서도 사용할 수 있게 해주는 훅입니다.

 

1. useRef의 기본 개념

 

useRef는 두 가지 주요 용도로 사용됩니다:

 

1. DOM 요소에 직접 접근:

리액트는 일반적으로 선언적으로 동작하지만, 가끔씩 DOM에 직접 접근해야 할 경우가 있습니다. 예를 들어, 포커스를 설정하거나, 특정 DOM 요소의 크기나 위치를 읽는 경우에 useRef를 사용할 수 있습니다.

2. 값을 저장:

useRef는 컴포넌트가 리렌더링될 때도 값을 기억할 수 있습니다. 그러나 상태(state)와는 달리, 값이 변경되더라도 컴포넌트를 다시 렌더링하지 않습니다. 따라서 렌더링과 관련 없는 값을 저장할 때 유용합니다.

 

2. useRef 훅 사용법

 

useRef초기값을 인수로 받아서 current 속성을 가진 객체를 반환합니다. 이 current 속성에 값을 저장할 수 있으며, 이 값은 컴포넌트가 리렌더링되더라도 유지됩니다.

 

기본 사용법

import React, { useRef } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null); // 초기값은 null

  const onButtonClick = () => {
    inputEl.current.focus();  // input 요소에 포커스를 설정
  };

  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

설명:

 

useRef(null): useRef를 호출하여 **inputEl**이라는 ref 객체를 생성하고, **초기값으로 null**을 설정합니다.

input 요소의 ref 속성에 **inputEl**을 전달하여 DOM 요소와 연결합니다.

**inputEl.current**는 실제 DOM 요소를 가리킵니다. 버튼을 클릭하면 **inputEl.current.focus()**를 호출하여 입력 필드에 포커스를 설정합니다.

 

3. useRef를 통해 DOM에 접근하기

 

useRef는 리액트의 DOM 요소에 직접 접근할 때 유용합니다. 이는 리액트의 선언적 방식과는 다르게, 특정 DOM 요소에 직접적인 명령을 내릴 수 있습니다.

 

DOM에 접근하는 예시

import React, { useRef } from 'react';

function ScrollToTopButton() {
  const divRef = useRef(null);

  const scrollToTop = () => {
    divRef.current.scrollIntoView({ behavior: 'smooth' });
  };

  return (
    <>
      <div ref={divRef} style={{ height: '150vh', backgroundColor: '#f5f5f5' }}>
        Scroll to see the button
      </div>
      <button onClick={scrollToTop}>Scroll to top</button>
    </>
  );
}

설명:

 

**divRef**는 useRef(null)을 통해 div 요소에 대한 참조를 저장합니다.

버튼을 클릭하면 **divRef.current.scrollIntoView**를 호출하여, div 요소로 스크롤을 이동시킵니다.

 

4. 값을 저장하는 용도로 useRef 사용하기

 

useRef는 DOM 참조뿐만 아니라 렌더링과 상관없는 값을 저장할 때도 유용합니다. 상태와 달리 useRef로 저장된 값은 컴포넌트가 다시 렌더링되어도 유지되며, 값을 수정해도 재렌더링이 발생하지 않습니다.

 

값 저장 예시: 이전 상태 추적

import React, { useState, useRef, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const prevCountRef = useRef(); // 이전 상태를 저장할 ref

  useEffect(() => {
    prevCountRef.current = count; // 매 렌더링 시 현재 count를 저장
  }, [count]); // count가 변경될 때마다 실행

  return (
    <div>
      <p>Current count: {count}</p>
      <p>Previous count: {prevCountRef.current}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

설명:

 

**prevCountRef.current**는 현재 렌더링된 count이전 렌더링 시점의 값으로 저장합니다.

**useEffect**에서 count가 변경될 때마다 이전 값을 저장하므로, 이전 count 값을 화면에 표시할 수 있습니다.

 

5. useRef와 상태(state)의 차이점

 

상태(state):

컴포넌트의 상태는 값이 변경되면 컴포넌트를 리렌더링합니다.

주로 UI 렌더링에 직접적인 영향을 미치는 값을 저장할 때 사용합니다.

useRef:

useRef로 저장된 값은 렌더링에 영향을 주지 않으며, 값이 변경되어도 리렌더링되지 않습니다.

주로 렌더링과 관련 없는 값을 저장하거나, DOM 요소에 접근하는 데 사용합니다.

 

상태와 useRef의 차이 비교 예시:

import React, { useState, useRef } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const renderCount = useRef(0); // 컴포넌트가 몇 번 렌더링되었는지 추적

  renderCount.current++; // 렌더링될 때마다 증가 (렌더링에 영향 없음)

  return (
    <div>
      <p>Count: {count}</p>
      <p>Render count: {renderCount.current}</p> {/* 리렌더링되지 않음 */}
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

설명:

 

**renderCount**는 useRef를 사용하여 렌더링 횟수를 추적하지만, 이 값이 변경되더라도 리렌더링을 트리거하지 않습니다.

**count**는 상태로 관리되며, 값이 변경되면 컴포넌트가 리렌더링됩니다.

 

6. 정리

 

useRef는 리액트에서 DOM 요소에 직접 접근하거나 렌더링과 관련 없는 값을 저장하는 데 유용한 훅입니다. useState와 달리 리렌더링을 발생시키지 않으면서 값을 유지할 수 있다는 점이 특징입니다. 이를 통해 특정 값이나 DOM 요소를 기억하고, 컴포넌트의 상태 관리렌더링 성능을 최적화할 수 있습니다.

 

요약:

 

DOM 접근: useRef는 컴포넌트에서 DOM 요소에 직접 접근하고 조작하는 데 사용됩니다.

렌더링과 무관한 값 저장: 렌더링과 관련 없는 값을 유지하고 추적할 수 있지만, 값이 변경되어도 리렌더링을 발생시키지 않습니다.

상태와의 차이: 상태는 값이 변경되면 컴포넌트를 리렌더링하지만, useRef는 리렌더링과 상관없이 값을 유지하고 수정할 수 있습니다.

'React' 카테고리의 다른 글

[React] 커스텀 훅 만들기  (2) 2024.09.15
[React] useRef 와 useEffect의 차이점  (0) 2024.09.14
[React] useEffect 훅, 의존성 배열  (0) 2024.09.13
[React] Hooks  (0) 2024.09.13
[React] 컴포넌트 라이프사이클  (1) 2024.09.13