React 컴포넌트에 ref prop 을 넘겨서 그 내부에 있는 HTML element에 접근을 하게 해주는 forwardRef() 함수에 대해서 알아보자

HTML Element의 ref prop

React에서 ref prop은 HTML element에 직접 접근하기 위해서 사용된다.

예를 들어, 아래 <Field/> 컴포넌트에서는 useRef() hook 함수로 생성한 inputRef 객체를 <input/> element의 ref prop으로 넘기고 있다. 이렇게 해주면 inputRef 객체의 current 속성에 <input/> element 레퍼런스가 할당되는데, 이를 통해 handleFocus() 이벤트 핸들러에서 <input/> element의 focus() 함수를 호출할 수 있다.

import React, { useRef } from "react";

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

  function handleFocus() {
    inputRef.current.focus();
  }

  return (
    <>
      <input type="text" ref={inputRef} />
      <button onClick={handleFocus}>입력란 포커스</button>
    </>
  );
}

React 컴포넌트의 ref prop

어떤 컴포넌트에서 다른 컴포넌트 내부에 있는 HTML element에 직접 접근해야 할 때가 종종 있다. 예를 들어 위 <Field/> 컴포넌트로 부터 <input/> element를 별도의 <Input/> 컴포넌트로 빼내보면 다음과 같다.

import React, { useRef } from "react";

function Input({ ref }) {
  return <input type="text" ref={ref} />;
}

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

  function handleFocus() {
    inputRef.current.focus();
  }

  return (
    <>
      <Input ref={inputRef} />
      <button onClick={handleFocus}>입력란 포커스</button>
    </>
  );
}

먼저 부모인 <Field/> 컴포넌트는 useRef() hook 함수로 생성한 inputRef 객체를 자식인 <Input/> 컴포넌트에 ref prop으로 넘긴다. 그러면 자식인 <Input/> 컴포넌트는 이 ref prop으로 넘어온 inputRef 객체를 다시 내부에 있는 <input/> element ref prop 으로 넘겨준다.

얼핏 그럴듯한 코드로 보이나 실제로 브라우저에서 실행을 해보면 콘솔에 다음과 같은 경고 메시지를 보게 된다.

Warning: Input: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (<https://reactjs.org/link/special-props>)
    at Input (<https://nqxh4.csb.app/src/Field.jsx:18:18>)
    at Field (<https://nqxh4.csb.app/src/Field.jsx:30:36>)
    at div
    at App

해석을 해보면 ref 는 prop로 사용할 수 없으므로 undefined가 설정될 것이고, 그래서 다른 prop을 사용해야한다는 것이다. 가이드대로 ref 대신 ref1 과 같이 다른 이름의 prop을 사요하도록 <Input/> 컴포넌트를 수정하여 문제를 해결할 수 있다.