TIL 230424 portal / 선택적 프로퍼티 문법

Chae·2023년 4월 24일

TIL 2304

목록 보기
5/8
post-thumbnail

🎆 오늘 한 것

  • 유데미 리액트 섹션 11 복습
  • 노마드 캐럿 마켓 섹션 5



✨ React - portal을 통해 모달 추가하기

🎆 작성 흐름

1. index.html에 모달을 포탈시킬 div 생성

  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="overlays"></div> 👈 모달과 백드롭을 포탈할 div
    <div id="root"></div>
  </body>

2. createPortal 이용해서 모달 컴포넌트 생성

import React from "react";
import classes from "./Modal.module.css";
import ReactDOM from "react-dom";

const Backdrop = (props) => {
  return <div className={classes.backdrop} onClick={props.onClose}></div>;
};

const ModalOverlay = (props) => {
  return (
    <div className={classes.modal}>
      <div className={classes.content}>{props.children}</div>
    </div>
  );
};

const portalElement = document.getElementById("overlays");

const Modal = (props) => {
  return (
    <>
      {ReactDOM.createPortal(<Backdrop />, portalElement)}
      {ReactDOM.createPortal(
        <ModalOverlay>{props.children}</ModalOverlay>,
        portalElement
      )}
    </>
  );
};

export default Modal;

3. 컴포넌트를 modal 컴포넌트로 감싸기

const Cart = () => {
  const cartitems = (
    <ul className={classes["cart-items"]}>
      {[{ id: "c1", name: "Sushi", amount: 2, price: 12.99 }].map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );

  return (
    <Modal>
      {cartitems}
      <div className={classes.total}>
        <span>Total Amount</span>
        <span>35.62</span>
      </div>
      <div className={classes.actions}>
        <button className={classes["button--alt"]}>Close</button>
        <button className={classes.button}>Order</button>
      </div>
    </Modal>
  );
};

🎆 portal 기능을 써서 modal을 만들면 좋은 점

  1. DOM 트리의 어디서나 모달을 렌더링할 수 있다. Portal은 모달을 root DOM 노드가 아닌 다른 위치에 렌더링할 수 있도록 해줌. 이로 인해 모달의 스타일링 및 레이아웃을 더욱 세밀하게 제어할 수 있다.

  2. 모달이 다른 요소들과 겹쳐있을 때, 포커스 이슈를 해결할 수 있다. 모달이 다른 요소들과 겹쳐있을 때, 사용자가 포커스를 잃어버리는 문제가 발생할 수 있다. 하지만 Portal을 사용하면 모달이 root DOM 노드 밖에서 렌더링되므로 이러한 문제를 해결할 수 있다.

  3. 모달의 성능을 향상시킬 수 있다. React는 모든 컴포넌트가 렌더링될 때마다 가상 DOM을 재생성하고 다시 렌더링한다. 하지만 Portal을 사용하면 모달이 root DOM 노드 밖에서 렌더링되므로 성능이 향상될 수 있다.

  4. 코드의 가독성과 유지보수성을 향상시킬 수 있다. Portal을 사용하면 모달과 관련된 로직과 스타일을 별도의 파일로 분리할 수 있다. 이렇게 하면 코드의 가독성과 유지보수성이 향상되며, 컴포넌트 간의 의존성도 줄어들어 유연한 구조를 구성할 수 있다.

즉, 코드의 유연성과 가독성, 성능 등 다양한 이점을 가지고 있음.



✨ TS - 선택적 프로퍼티 문법

interface LayoutProps {
  title?: string;
  canGoBack?: boolean;
  hasTabBar?: boolean;
  children: React.ReactNode;
}

객체 타입에서 일부 프로퍼티가 선택적이라는 것을 명시하는 방법


🎆 예제

interface Person {
  name: string;
  age?: number;
}

위 인터페이스는 name 프로퍼티가 필수이지만 age 프로퍼티는 선택적이다. 따라서 아래의 두 객체는 모두 Person 타입에 할당될 수 있다.

const person1: Person = { name: 'Alice' };
const person2: Person = { name: 'Bob', age: 30 };

이러한 선택적 프로퍼티는 옵셔널한 인자를 받는 함수나 클래스 생성자 등에서 유용하게 사용될 수 있다. 함수의 인자를 선택적으로 받을 수 있게 하려면 인자 이름 뒤에 ?를 붙이면 됨. 예를 들어 다음 함수는 age 인자를 선택적으로 받는다.

function greet(name: string, age?: number) {
  console.log(`Hello, ${name}!`);
  if (age !== undefined) {
    console.log(`You are ${age} years old.`);
  }
}

age 인자가 생략될 경우 undefined 값이 할당되므로, 이를 검사하여 You are ${age} years old. 메시지를 출력하도록 구현.


이전 파이널 프로젝트는 이 문법을 몰라서 계속 프롭스타입으로 | undefined 같은 걸 적었는데 이런 편리한 문법이 있었다... 타입스크립트 조금 더 열심히 공부하고 프로젝트 들어갈 걸


profile
TIL(거의 일기)위주. 공부한 것들은 정리해서 깃허브에 올리고 있습니다. 개인적으로 공부 중인 내용들이기 때문에 틀린 정보가 있을 수 있습니다.

0개의 댓글