TIL

forwardRef: 자식 컴포넌트에 ref를 전달하기

nana-log 2024. 2. 22. 23:04

forwardRef()란?

React에서 일반적으로 사용할 수 없는 prop이 몇 가지 있다. 그 중 ref prop도 HTML Element 접근이라는 특수한 용도로 사용되기 때문에 일반적인 prop으로 사용할 수 없다.

React Component에서 ref prop을 사용하려면 forwardRef()라는 함수를 사용해야 한다. React Component를 forwardRef() 함수로 감싸주면, 컴포넌트 함수는 2번째 매개변수를 갖게 되는데 이를 통해 ref prop을 넘길 수 있다.

import { useRef } from "react";

const Input = ref => {
    return <input type="text" ref={ref} />;
};

const Field = () => {
    const inputRef = useRef(null);
    const focusHandler = () => {
        inputRef.current.foucus();
    };

    return( 
        <> 
            <Input ref={inputRef} /> 
            <button onClick={focusHandler}>focus</button> 
        </> 
    ); 

Component에 useRef() 함수로 생성한 inputRef 객체가 있다. 이 객체를 자식인 Component에 ref prop으로 넘긴다. 그러면 자식 Component는 ref prop으로 넘어온 inputRef 객체를 다시 내부에 있는 Element의 ref prop으로 넘겨준다.
 
하지만 위 예시에서는 ref를 prop으로 넘겨줬기 때문에 경고 메세지가 뜬다.
왜 경고 메세지가 뜰까?

ref는 React에서 특별하게 취급하는 prop이다. ref는 컴포넌트에 대한 참조를 생성하고, 이를 통해 컴포넌트의 인스턴스나 DOM 요소에 접근할 수 있게 한다.

그러나 ref는 일반적인 prop와는 달리, 컴포넌트에게 직접적으로 전달되지 않는다. 즉, 컴포넌트의 props 객체를 통해 ref에 접근할 수 없다. 따라서 props.ref와 같은 방식으로 ref를 사용하려고 하면 undefined가 반환되며, 경고 메시지가 출력됩니다.

이는 React의 설계 철학에 따른 것이다. React는 선언적인 패러다임을 지향하며, 컴포넌트의 상태는 주로 stateprops를 통해 관리되어야 한다. ref를 통한 직접적인 컴포넌트 조작은 이 패러다임을 벗어나는 것으로, 이를 방지하기 위해 ref는 특별하게 취급된다.

만약 부모 컴포넌트에서 생성한 ref를 자식 컴포넌트에게 전달하고 싶다면, forwardRef를 사용해야 한다. 이를 통해 ref를 자식 컴포넌트의 인스턴스나 DOM 요소에 직접 연결할 수 있다.

 

이제 forwardRef()를 적용해보자.

import { useRef, forwardRef } from "react";

const Input = forwardRef((props, ref) => {
    return <input type="text" ref={ref} />;
});

const Field = () => {
    const inputRef = useRef(null);
    const focusHandler = () => {
        inputRef.current.foucus();
    };

    return( 
        <> 
            <Input ref={inputRef} /> 
            <button onClick={focusHandler}>focus</button> 
        </> 
    ); 
};

Component를 forwardRef()로 감싸주고, 2번째 매개변수로 ref를 받아 Element에 ref prop을 넘겼더니 경고 메세지 없이 버튼을 클릭하면 input에 포커스가 된 것을 확인할 수 있다.
 
 
참고
https://dori-coding.tistory.com/entry/React-ref를-prop으로-넘기기-forwardRef