ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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 />
      );
    });

     

    참고 : https://dori-coding.tistory.com/entry/React-ref%EB%A5%BC-prop%EC%9C%BC%EB%A1%9C-%EB%84%98%EA%B8%B0%EA%B8%B0-forwardRef

Designed by Tistory.