TIL

useRef, useImperativeHandle, createPortal

너구리개발자 2024. 5. 30. 02:13

 

 

 

createPortal

 createPortal은 React에서 제공하는 메서드로, 부모 컴포넌트의 DOM 계층 밖에 있는 DOM 노드에 자식 컴포넌트를 렌더링할 수 있게 해줍니다.
용도: 모달, 툴팁, 다른 콘텐츠 위에 나타나야 하는 UI 요소를 렌더링할 때 자주 사용됩니다.

 

 

useRef

 

 useRef는 컴포넌트가 리렌더링 되더라도 값이 변하지 않고 유지되는 변수를 관리하는 훅입니다. 값이 변경되어도 컴포넌트 리렌더링을 트리거하지 않습니다.
용도: 주로 DOM 요소에 직접 접근하거나 렌더링 간에 값을 유지해야 할 때 사용됩니다.

 


useImperativeHandle

useImperativeHandle은 부모 컴포넌트에서 ref를 사용할 때 노출되는 인스턴스 값을 사용자 정의할 수 있는 훅입니다. 이를 통해 부모 컴포넌트가 접근할 수 있는 값과 메서드를 제어할 수 있습니다.
용도: 보통 forwardRef와 함께 사용하여 부모 컴포넌트에 명령형 메서드를 노출하는 컴포넌트를 만들 때 사용됩니다.

 

 

 

 


사용 예시
createPortal, useRef, useImperativeHandle을 혼합하여 모달 컴포넌트를 만들고 부모 컴포넌트에서 이를 제어할 수 있는 예시입니다:

 

// 모달 컴포넌트
const Modal = forwardRef((props, ref) => {
  const [isOpen, setIsOpen] = useState(false);

  // 부모 컴포넌트에 open과 close 메서드를 노출
  useImperativeHandle(ref, () => ({
    open: () => setIsOpen(true),
    close: () => setIsOpen(false),
  }));

  // 모달 콘텐츠를 포탈로 렌더링
  if (!isOpen) return null;
  return createPortal(
    <div className="modal">
      <div className="modal-content">
        {props.children}
        <button onClick={() => setIsOpen(false)}>닫기</button>
      </div>
    </div>,
    document.body // 또는 특정 DOM 노드
  );
});

// 부모 컴포넌트
const App = () => {
  const modalRef = useRef();

  const openModal = () => {
    if (modalRef.current) {
      modalRef.current.open();
    }
  };

  return (
    <div>
      <h1>React Portals와 Imperative Handle 예시</h1>
      <button onClick={openModal}>모달 열기</button>
      <Modal ref={modalRef}>
        <h2>모달 콘텐츠</h2>
        <p>React Portals, useRef, useImperativeHandle을 사용하는 예시입니다.</p>
      </Modal>
    </div>
  );
};



설명

 

Modal 컴포넌트:
forwardRef를 사용하여 부모 컴포넌트로부터 전달받은 ref를 전달합니다.
useImperativeHandle을 사용하여 부모 컴포넌트에 open과 close 메서드를 노출합니다.
createPortal을 사용하여 자식 콘텐츠를 부모 컴포넌트의 DOM 계층 밖에 렌더링합니다.


App 컴포넌트:
모달 컴포넌트를 참조하기 위해 useRef를 정의합니다.
"모달 열기" 버튼이 클릭되면 ref를 통해 모달 컴포넌트의 open 메서드를 호출합니다.

 

 


결론
이 예시는 createPortal을 사용하여 부모 컴포넌트의 DOM 계층 밖에 모달을 렌더링하고, useRef를 사용하여 모달 컴포넌트를 참조하며, useImperativeHandle을 사용하여 부모 컴포넌트가 모달의 열림/닫힘 상태를 제어할 수 있게 하는 방법을 보여줍니다.