Udemy React 강의 139번 정리
리액트에서 ref는 원래 DOM 요소에 연결할 때 사용한다.
<input ref={inputRef} />
하지만 커스텀 컴포넌트 내부의 DOM 요소에 ref를 연결하고 싶을 때는 상황이 조금 까다롭다.
강의 예제에서는 TimerChallenge → ResultModal 모달을 띄우기 위해 dialog 요소에 ref를 연결해야 한다.
다음 코드는 가능하다.
<dialog ref={dialog} />
하지만 다음은 기본적으로 동작하지 않는다.
<ResultModal ref={dialog} /> // 커스텀 컴포넌트라서 직접 ref 연결 불가
그래서 커스텀 컴포넌트가 ref를 전달받도록 처리해줘야 한다.
React 19에서는 아래 코드가 동작한다.
TimerChallenge.jsx
const dialog = useRef();
<ResultModal ref={dialog} />
ResultModal.jsx
export default function ResultModal({ ref }) {
return <dialog ref={ref}> ... </dialog>;
}
그리고 TimerChallenge 안에서는 dialog.current.showModal(); 이렇게 하면 바로 dialog 요소를 조작할 수 있다.
최신 리액트는 ref를 일반 prop처럼 받을 수 있게 API가 바뀜 (그래서 forwardRef 없어도 됨)
하지만 구버전 React에서는 위 방식이 안 됨. 즉, ref를 커스텀 컴포넌트에 직접 잔달할 수 없었음. 그래서 구버전에서는 forwardRef를 사용해야 한다.
ResultModal.jsx
import { forwardRef } from 'react';
const ResultModal = forwardRef(function ResultModal(props, ref) {
return (
<dialog ref={ref}>{props.children}</dialog>
);
});
export default ResultModal;
여기서 forwardRef가 컴포넌트를 특별한 형태로 감싸줌. 그래서 컴포넌트는 두 번째 인자로 ref를 전달받는다. (props, ref)
모달을 열기 위해 showModal()을 호출해야 하기 때문임.
dialog.current.showModal();
<dialog> 요소showModal()은 브라우저 내장 메서드따라서 ref로 DOM에 접근해야 한다는 것.