0Pricing
React Academy · 강의

Portal로 툴팁 및 드롭다운 메뉴 만들기

Portal을 사용해 overflow-hidden 컨테이너 밖에 툴팁과 드롭다운을 렌더링합니다.

Portal로 툴팁 및 드롭다운 메뉴 만들기은(는) CoddyKit의 무료 React Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 React Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. React Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

환영합니다

이 레슨에서는 React 포털을 사용하여 document.body에 렌더링되는 툴팁과 드롭다운 컴포넌트를 만들고, 부모의 overflow-hidden 및 z-index 쌓임 맥락 제약을 벗어나도록 합니다.

오버플로 문제

트리거 버튼을 기준으로 배치된 툴팁은 조상 요소 중 하나라도 `overflow: hidden` 또는 `overflow: scroll`을 사용하면 잘립니다. 포털을 통해 툴팁을 document.body로 옮기면 이 문제가 완전히 해결됩니다.

위치 지정 전략

포털로 렌더링된 툴팁을 올바르게 배치하려면 `getBoundingClientRect()`로 트리거 요소의 경계 사각형을 측정하고 스크롤 위치를 반영한 절대 좌표를 계산하십시오.
const rect = triggerRef.current.getBoundingClientRect();
const top = rect.bottom + window.scrollY + 8;
const left = rect.left + window.scrollX;

툴팁 컴포넌트

children을 감싸고 트리거에 ref를 연결하며, 마우스를 올렸을 때 위치가 계산된 툴팁 상자를 포털로 렌더링하는 Tooltip을 만드십시오.
function Tooltip({ content, children }) {
  const [visible, setVisible] = useState(false);
  const [pos, setPos] = useState({ top: 0, left: 0 });
  const ref = useRef();

  const show = () => {
    const r = ref.current.getBoundingClientRect();
    setPos({ top: r.bottom + window.scrollY + 4,
             left: r.left + window.scrollX });
    setVisible(true);
  };

  return (
    <span ref={ref} onMouseEnter={show} onMouseLeave={() => setVisible(false)}>
      {children}
      {visible && createPortal(
        <div style={{ position:'absolute', top: pos.top, left: pos.left }}
             className="tooltip">{content}</div>,
        document.body
      )}
    </span>
  );
}

스크롤 및 크기 조정 시 위치 업데이트

툴팁이 표시된 상태에서 사용자가 스크롤하면 위치가 오래된 값이 됩니다. `scroll` 및 `resize` 이벤트를 수신하여 위치를 다시 계산하거나 툴팁을 닫으십시오.
useEffect(() => {
  if (!visible) return;
  const update = () => setVisible(false);
  window.addEventListener('scroll', update, true);
  window.addEventListener('resize', update);
  return () => {
    window.removeEventListener('scroll', update, true);
    window.removeEventListener('resize', update);
  };
}, [visible]);

드롭다운 메뉴 구조

드롭다운 메뉴는 툴팁과 동일한 패턴을 따릅니다. 트리거 버튼이 메뉴를 표시하거나 숨기고, 메뉴는 포털을 통해 렌더링되며, 바깥쪽 클릭 handler가 메뉴를 닫습니다.

바깥쪽 클릭 handler

메뉴 바깥쪽 클릭을 감지하려면 `document`에서 `mousedown` 수신기를 사용하십시오. 클릭 대상과 메뉴 및 트리거 ref를 비교하여 닫을지 결정하십시오.
useEffect(() => {
  if (!open) return;
  const handler = (e) => {
    if (!menuRef.current?.contains(e.target) &&
        !triggerRef.current?.contains(e.target)) {
      setOpen(false);
    }
  };
  document.addEventListener('mousedown', handler);
  return () => document.removeEventListener('mousedown', handler);
}, [open]);

드롭다운의 키보드 탐색

ArrowDown/ArrowUp으로 메뉴 항목 사이를 이동하고, Enter로 선택하며, Escape로 닫도록 구현하십시오. 상태에서 포커스된 인덱스를 추적하고 메뉴 항목에서 `.focus()`를 프로그래밍 방식으로 호출하십시오.

위치 지정 라이브러리 사용하기

프로덕션에서는 **@floating-ui/react**(이전 이름 Popper.js)를 사용하십시오. 이 라이브러리는 뷰포트 가장자리 근처에서 위치를 바꾸는 flip, 툴팁이 보이는 상태를 유지하는 shift, 화살표 위치 지정을 자동으로 처리합니다.
import { useFloating, flip, shift } from '@floating-ui/react';

const { refs, floatingStyles } = useFloating({
  middleware: [flip(), shift()],
});

접근성: 툴팁을 위한 ARIA

툴팁 요소에 `role='tooltip'`을 추가하고 트리거의 id를 가리키는 `aria-describedby`를 추가하십시오. 이렇게 하면 스크린 리더가 툴팁 콘텐츠를 안내할 수 있습니다.
<button aria-describedby="tip1">Hover me</button>
{visible && createPortal(
  <div id="tip1" role="tooltip">Helpful text</div>,
  document.body
)}

빠른 확인

포털로 렌더링된 툴팁의 올바른 화면 위치를 어떻게 계산합니까?

복습

포털을 사용하면 툴팁과 드롭다운이 overflow가 숨겨진 부모 요소의 제약에서 벗어날 수 있습니다. getBoundingClientRect로 트리거의 위치와 크기를 측정하고, 절대 위치 지정을 위해 스크롤 오프셋을 더하세요. 바깥 영역을 클릭하거나 스크롤하면 닫히도록 하고, 접근성을 위해 ARIA 속성도 추가하세요.

과정 완료

축하합니다! **React의 포털 및 모달** 과정을 완료하셨습니다. 이제 CSS의 쌓임 제약에서 벗어나면서도 접근성을 갖추고 올바르게 배치되는 모달, 툴팁, 드롭다운을 만들 수 있습니다.

자주 묻는 질문

“Portal로 툴팁 및 드롭다운 메뉴 만들기” 강의는 무료인가요?

네 — “Portal로 툴팁 및 드롭다운 메뉴 만들기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 React Academy 강의 전체를 잠금 해제할 수 있습니다. React Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“Portal로 툴팁 및 드롭다운 메뉴 만들기”에서 뭘 배우나요?

Portal을 사용해 overflow-hidden 컨테이너 밖에 툴팁과 드롭다운을 렌더링합니다. 브라우저에서 직접 실행하는 실습 코드로 React Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

React Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 React Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“Portal로 툴팁 및 드롭다운 메뉴 만들기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 React Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 React Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. React Portal이란 무엇인가요
  2. Portal로 모달 구성 요소 만들기
  3. 모달의 포커스 및 키보드 트랩 처리
  4. Portal로 툴팁 및 드롭다운 메뉴 만들기
← React Academy(으)로 돌아가기