forwardRef: 자식 컴포넌트에 ref를 전달하기
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는 선언적인 패러다임을 지향하며, 컴포넌트의 상태는 주로 state
와 props
를 통해 관리되어야 한다. 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