
우리는 보통 DOM을 조작하기 위해 useRef를 사용한다. 컴포넌트의 styles 등을 조작하기 위해 <Component ref={ref} />를 사용하곤 한다. 그러나 리액트 컴포넌트는 ref인자를 받지 않는다.
리액트 컴포넌트로 ref를 받는 방법을 알아 보도록 하자.
forwardRef를 사용하면 컴포넌트에 ref를 전달할 수 있다.
render: 컴포넌트 렌더 함수를 받는다. 렌더 함수는 props와 ref를 받는 컴포넌트이다.
일반 컴포넌트와 동일하게, ref를 받을 수 있는 리액트 컴포넌트를 반환한다.
다음과 같이 기본적인 컴포넌트가 있다.
export const Component = (props) => {
//❌ => ref에 오류가 발생
return (
<div ref={props.ref}>...</div>
)
}
ref를 전달할 수 있는 컴포넌트는 forwardRef를 사용한다.
자식 컴포넌트
export const Component = forwardRef((props, ref) => {
//✅ => ref를 전달받을 수 있음
return (
<div ref={ref} {...props}>...</div>
)
});
부모 컴포넌트
export const App = () => {
const ref = useRef(null);
return (
<Coponent ref={ref} />
)
}
타입스크립트에는 useRef의 타입과 forwardRef의 ref인자의 타입이 같아야 한다.
자식 컴포넌트
export const Component = forwardRef<HTMLDIVElement, Props>(
({ ...props }, ref) => {
return (
<div ref={ref} {...props}>...</div>
)
}
)
부모 컴포넌트
export const App = () => {
const ref = useRef<HTMLDivElement>(null);
return (
<Coponent ref={ref} />
)
}
forwardRef를 정리하면서 ref를 사용할 때 유의점도 같이 알아보자
ref.current를 쓰거나 읽으면 안된다.
//❌ => 쓰기 작업
ref.current = 100;
//❌ => 읽기 작업
<div>{ref.current}</div>
DOM조작 시 useRef에 null 초기화 해야 한다.
const ref = useRef(null);