본문 바로가기

Study/React

Fragment & Portal

React tools for semantic HTML

React.Fragment 

JSX 코드는 다음과 같은 한계를 가지고 있다.

 

  1. Root 요소는 1개보다 많을 수 없다. 
    • jsx 컴포넌트는 리액트의 createElement 함수를 실행하는데, 이 함수는 배열을 반환한다.
    • root element가 여러 개라면 여러 개의 배열을 반환해야 한다. => JS에서 유효하지 않은 구문이다. 
    • children element는 nested array가 되기 때문에 유효하다.
      • React.createElement( 'div', { className... }, createElement('p', , ), ...)
  2. div soup | 1의 이유로 <div> 태그를 남발하게 될 수 있다. => no semantic, low performance, hard to add styles 
    • div 대신 [ 배열 ]을 사용하면, 그 안에 jsx 코드를 반환할 수 있다. 단, 모든 요소에 key 프로퍼티를 설정해 주어야 한다. 

 

이런 jsx의 한계를 해결하기 위해 다음과 같은 솔루션을 사용할 수 있다. 

 

const Wrapper = props => {
  return props.children;
}

 

  1. div 대신 Wrapper 객체를 root element로 사용하면, 실제 html element로는 아무 것도 추가되지 않기 때문에 유용하다. 
  2. 이 객체를 직접 만들지 않아도 된다. => 리액트에서 제공하는 <React.Fragment > 가 있다. 아래와 같이 사용할 수 있다.  
    • <React.Fragment > </ React.Fragment >
    • <Fragment > </ Fragment>
    • <> </ > 

ReactDOM.createPortal

what is portal? 

portal을 이용하면 index.html의 어떤 요소를 선택하고, 그 위치로 jsx 컴포넌트 마크업을 옮길 수 있다. 즉 렌더링된 element를 다른 위치로 옮긴다.

 

portal은 언제 사용할까? modal 창이나, backdrop, side drawer와 같은 over-lay UI(z-index 값이 큰 UI)의 경우에 유용하게 사용할 수 있다. 예를 들어 form의 제출 형식이 유효하지 않을 때 error modal을 보여준다고 한다면, 이 modal은 form에 속해 있기 보다는, body 태그의 direct child element인 것이 더 semantic하다. 이처럼 마크업 위치를 다른 곳으로 옮기고 싶을 때 portal을 이용할 수 있다.

how to use portal? 

<body>
  <!-- modal이 위치하게 될 곳을 만든다 --> 
  <div id="modal-root"></div>
  <div id="root"></div>
</body>

 

import ReactDOM from 'react-dom';

const Modal = props => {
  return (
    <>
      <div className={classes.backdrop} onClick={props.onConfirm} />
      <section 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>
      </section>
    </>  
  )
}

const ErrorModal = (props) => {
  return (
  <>
    {ReactDOM.createPortal(<Modal onClick={...} />, document.getElementById('modal-root'))});
  </>
};

export default ErrorModal;

 

  • createPortal 
    1. 첫번째 인자로 jsx 컴포넌트를 전달한다.
    2. 두번째 인자로 해당 컴포넌트가 포함 될 element를 전달한다. 

'Study > React' 카테고리의 다른 글

useEffect  (0) 2022.06.19
useRef  (0) 2022.06.18
Component Styling  (0) 2022.06.18
Conditional contents  (0) 2022.06.17
Dynamic List  (0) 2022.06.17