-
[React] ref를 prop으로 넘기기 - forwardRef()Frontend/React 2023. 4. 28. 21:10
우선, ref는 React에서 DOM에 직접 접근하기 위해 사용한다.
사용방법은 우선 useRef hook을 선언하여 ref 객체를 생성한 다음 원하는 Element의 ref 값을 넘기면 된다.
import { useRef } from 'react'; export default fuction App() { const inputRef = useRef(null); const focusHandler = () => { inputRef.current.disabled = false; inputRef.current.focus(); }; const resetHandler = () => { inputRef.current.disabled = true; inputRef.current.value = ""; }; return <Input type="text" ref={inputRef} disabled />
이렇게 되면 InputRef 객체의 current 속성에 <input> element의 래퍼런스가 저장된다.
그리고 inputRef 객체를 통해 input element를 제어할 수 있다.
이렇게 ref prop은 HTML Element 접근이라는 특수한 용도로 사용되기 때문에, 일반적인 prop으로 사용할 수 없다.
아래와 같은 상황을 생각해보자.
주로 Tab이나 Modal을 만들 때 외부에서 ref를 정의하여 <Tab />이나 <Modal />에 props로 넘겨주어야 될 일이 많다.
흔한 서비스 중 하나로, useOnClickOutside 함수를 적용할 때를 예시로 들어보자.
// useOnClickOutside.ts
import { useEffect, useRef } from 'react'; export const useOutsideClick = (callback: any) => { const ref = useRef<any>(); useEffect(() => { const handleClick = (event: any) => { if (ref.current && !ref.current.contains(event.target)) { callback(); } }; document.addEventListener('click', handleClick); return () => { document.removeEventListener('click', handleClick); }; }, [callback]); return ref; };
// Detail.tsx
export default function Detail() { const [openModal, setOpenModal] = useState<boolean>(false); const modalRef = useOutsideClick(() => { if (openModal) { setOpenModal(false); } }); return <> isDetailModalOpen && <Modal ref={modalRef} /> </> }
Modal.tsx가 따로 정의되어있는 상태에서 prop로 ref를 그냥 넘기면
Type '{ ref: MutableRefObject<any>; }' is not assignable to type 'IntrinsicAttributes & ForwardedRef<HTMLDivElement>'. Property 'ref' does not exist on type 'IntrinsicAttributes & ForwardedRef<HTMLDivElement>'.ts(2322)
위와 같은 아래가 뜬다.
ref를 props로 넘기려면 ref를 넘기려는 React component를 forwardRef()로 감싸주면 함수는 ref라는 매개변수를 갖게 되는데 그 매개변수에 prop을 넘길 수 있다.
그래서, Modal이라는 React component를 아래와 같이 수정해 주면 된다.
import { ForwardedRef, forwardRef} from 'react'; export default forwardRef(function Modal( _, ref: ForwardedRef<HTMLDivElement> ) { return ( <div /> ); });
'Frontend > React' 카테고리의 다른 글
React를 활용한 OAuth 2.0 카카오 로그인 연동 (0) 2023.04.24 React Router - BrowserRouter vs HashRouter (0) 2023.04.24 React 컴포넌트 렌더링 전체 과정 정리 (feat. useLayoutEffect vs useEffect) (0) 2023.03.25 React Virtual DOM 비교 커밋 원리와 얕은 비교 (0) 2023.03.25 useLayoutEffect hook 필요성 및 사용 예시 (0) 2023.03.07