공통 컴포넌트에 관하여 공부하던 중 이 글을 보고 forwardRef를 알아보게 되었다.
2-3. forwardRef
form 요소를 공통컴포넌트로 만들다 보면 놓치기 쉬운 것이 ref일 것입니다. 리액트에서 요소 참조를 위해 사용되는 ref는 일반적으로 prop으로 전달할 수 없으므로 forwardRef를 사용해야 합니다. 만약 forwardRef로 감싸지 않는다면 내부적으로 ref를 사용해야 하는 react-hook-form 같은 일부 라이브러리 사용에 제약이 있을 수 있습니다.
import { InputHTMLAttributes, forwardRef } from 'react'; interface Props extends InputHTMLAttributes<HTMLInputElement> {} export default forwardRef<HTMLInputElement, Props>(function Checkbox( { ...rest }, ref, ) { return <input type="checkbox" ref={ref} {...rest} />; });
공식 문서를 찾아봤다.
forwardRef lets your component expose a DOM node to parent component with a ref.
forwardRef는 부모 컴포넌트에 컴포넌트가 ref를 통해 DOM 노드를 노출하게 한다.
그렇다면 forwardRef로 정의되지 않은 컴포넌트는 부모 컴포넌트가 자식 컴포넌트의 DOM에 접근할 수 없다는 것이다.
예제를 만들어 확인해봤다.
보다시피 기존 함수형 컴포넌트로 정의된 ChildA는 부모 컴포넌트가 ref를 통해 DOM에 접근할 수 없는 것을 확인할 수 있다.
이는 리액트의 설계 원칙인 캡슐화와 추상화, 함수형 컴포넌트의 특성, 컴포넌트 간의 명확한 경계 유지, 상태와 생명주기 관리의 복잡성 등의 문제로 부모 컴포넌트에서 자식 컴포넌트로의 직접적인 DOM 접근은 forwardRef()를 통해서만 가능하도록 하였다고 한다.
forwardRef 사용시 코드의 가독성 저하, typescript에서의 타이핑 복잡성 등의 불편을 해소할 수 있게 된다.
한편, React 19부터는 forwardRef를 사용하지 않아도 앞서 정의했던 자식 컴포넌트의 props에 바로 ref를 넘겨 사용할 수 있다고 한다.