[React] useRef, forwardRef 사용법

profile
마릴린벅시
2023. 2. 12. 22:17프론트엔드

 

useRef

useRef는 리액트 컴포넌트에서 값을 유지하는데 사용되는 편리한 함수다. useRef 훅은 값을 가리키는 레퍼런스 객체를 반환한다. 레퍼런스 객체는 current 속성을 가지고 있어, 이 속성을 통해 값에 접근하고 수정할 수 있다.

function TextInputWithFocusButton() {

  const inputEl = useRef(null);

  const onButtonClick = () => {
    // `current` 속성은 input엘리먼트를 가리키고 있다.
    inputEl.current.focus();
  };
  
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

useRef는 여러 가지 용도로 사용될 수 있다. 예를 들어, DOM 엘리먼트에 레퍼런스를 설정하여 이를 조작하거나(위 코드처럼), 타이머에서 값을 유지하거나, 어떤 값을 기억하여 컴포넌트의 렌더링 상태에 영향을 미치지 않는 값을 유지하는 등의 용도로 사용될 수 있다.

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

function Timer() {
  const [seconds, setSeconds] = useState(0);
  //useRef 훅을 사용하여 intervalRef라는 ref 객체를 생성. 
  //이 객체는 setInterval 함수의 반환 값을 저장하여 타이머를 제어할 수 있게 한다.
  const intervalRef = useRef();

  //startTimer 함수를 호출하면 setInterval 함수가 실행되고,
  function startTimer() {
    intervalRef.current = setInterval(() => {
      setSeconds(seconds => seconds + 1);
    }, 1000);
  }

  //stopTimer 함수를 호출하면 clearInterval 함수가 실행된다.
  function stopTimer() {
    clearInterval(intervalRef.current);
  }

  return (
    <div>
      <div>{seconds} seconds have elapsed</div>
      <button onClick={startTimer}>Start timer</button>
      <button onClick={stopTimer}>Stop timer</button>
    </div>
  );
}

export default Timer;

useRef의 값은 같은 컴포넌트 내에서 생명주기 동안 계속 유지된다. 그러므로 렌더링 상태에 영향을 미치지 않으면서, 값을 유지하고 조작할 수 있다.


forwardRef

forwardRef는 리액트에서 부모 컴포넌트에서 자식 컴포넌트로 DOM요소에 대한 참조를 전달할 수 있도록 하는 고차 컴포넌트다. 이는 요소의 크기나 위치 측정하기, 애니메이션을 시작하거나 포커스, 텍스트 선택, 미디어 재생을 관리하는 경우에 자식 요소의 DOM 노드에 직접 액세스 해야 하는 경우에 유용하다. forwardRef는 함수형 컴포넌트를 forwardRef함수로 감싸고 인수로 전달하여 사용된다.

import React, { forwardRef } from 'react';

//자식 컴포넌트
const MyInput = forwardRef((props, ref) => {
  return (
    <input type="text" ref={ref} {...props} />
  );
});

//부모 컴포넌트
function App() {
  const inputRef = React.useRef(null);

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

  return (
    <div>
      <MyInput ref={inputRef} />
      <button onClick={focusInput}>Focus the input</button>
    </div>
  );
}

위 코드는 부모 컴포넌트에서 자식 컴포넌트의 input DOM요소에 대한 참조를 얻기 위해 forwardRef를 사용한것이다.

자식 컴포넌트의 ref prop에서 참조를 가져올 수 있으며, 이를 통해 특정 작업(여기서는 focus)를 수행할 수 있다.

반응형