TIL Fragments / Portals

이정민·2022년 12월 12일
0
post-thumbnail

Fragment 사용하는 이유

Fragments는 DOM에 별도의 노드를 추가하지 않고 여러 자식을 그룹화

의미없는 <div>의 사용은 지양하자!

프로젝트 코드를 작성할 때 <div>를 무의식적으로 많이 사용했는데<div>를 사용하면 HTML의 DOM 구조에도 <div>는 적용되기 때문에 <div>대신 fragment를 사용해야한다.

<></>를 사용한다면 map과 같이 key가 필요할 때 key값을 지정할 수 없지만 <React.Fragment></React.Fragment>를사 사용한다면 key값을 지정할 수 있다.

Portals란?

Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링

모달, 드로어, 다이어로그와 같은 오버레이나 연관 컴포넌트를 사용할 때 사용된다.

<div onClick={handleClick}>Click me! I am a bad Button</div>
위의 코드는 동작은 하지만 좋은 코드는 아니다.

사용예시

포탈을 사용할 때는 크게 두가지가 필요하다.
1. 컴포넌트를 이동할 장소
2. 컴포넌트에게 어디로 이동하라 지시

1번의 과정을 다음과 같다.

모달을 만들고 싶을 때 우선 backdrop과 모달 컴포넌트를 분리 후 
index.html파일에 
<body>
  <div id="backdrop-root"></div>
  <div id="overlay-root"></div>
  <div id="root"></div>
</body>

2번을 위해서는 일단 이동할 컴포넌트를 분리한다.

const Backdrop = (props) => {
    return <div className={classes.backdrop} onClick={props.onConfirm} />;
  };
  const ModalOverlay = (props) => {
    return (
      <Card className={classes.modal}>
        <header className={classes.header}>
          <h2>{props.title}</h2>
        </header>
        <div className={classes.content}>
          <p>{props.message}</p>
        </div>
        <footer className={classes.actions}>
          <Button onClick={props.onConfirm}>Okay</Button>
        </footer>
      </Card>
    );
  };

createPortal()은 두가지 인수가 필요한데 첫번째로는 렌더링 되어야하는 리액트 노드 =><Backdrop onClick={props.onConfirm} />
두번째로는 앞의 노드가 렌더링 되어야하는 실제 DOM의 컨테이너를 가르키는 포인터이다. => document.getElementById("backdrop-root")

    {ReactDOM.createPortal(
        <Backdrop onConfirm={props.onConfirm} />,
        document.getElementById("backdrop-root")
      )}
      {ReactDOM.createPortal(
        <ModalOverlay
          title={props.title}
          message={props.message}
          onConfirm={props.onConfirm}
        />,

        document.getElementById("overlay-root")
      )}

0개의 댓글