createPortal, forwardRef

LOOPY·2022년 8월 29일
0
post-thumbnail

1. React.createPortal

부모 컴포넌트의 DOM 계층 구조 바깥에 있는 (render 영역 밖에 있는) DOM 노드로 자식을 렌더링하는 기능

// indexl.html의 <body>

<div id="root"></div>
<div id="modal"></div>

// index.css

#modal {
  position: absolute;
  top: 0;
  left: 0;
}

// ./src/components/Modal.jsx

import ReactDOM from 'react-dom';

const Modal = ({children}) => 
	// children을 modal DOM의 후손 요소로 삽입
	ReactDOM.createPortal(children, document.querySelector("#modal"));

export default Modal;

// App.js

function App() {
  const [visible, setVisible] = useState(false);

  const open = () => {
    setVisible(true);
  }
  const close = () => {
    setVisible(false);
  }

  return <div>
    <button onClick={open}>open</button>
    {visible && (
      <Modal>
        <div 
          style={{
            width: '100vw',
            height: '100vh',
            background: "rgba(0, 0, 0, 0.5)",
          }} 
        onClick={close}
        >
          Hello
        </div>
      </Modal>
    )}
  </div>
}

이 때, Modal은 createPortal을 사용해 id가 modal인 엘리먼트에 render되도록 설정된 상태

👩🏻 따라서 컴포넌트를 특정한 다른 div 안에 넣고싶다면 root 벗어난 곳에서 처리할 수 있도록 createPortal 사용해볼 것! (특히 모달 팝업이나 알림창 구현 시 유용)


2. React.forwardRef

하위 컴포넌트의 ref를 상위 컴포넌트에서 사용하게 해주는 기능
이 때 forwardRef()의 첫번째 매개변수는 props, 두번째 매개변수는 ref

// ./src/components/MyInput.jsx

import React from "react";
import { forwardRef } from "react";

export default forwardRef(function MyInput(props, ref) {
  return (
    <div>
      <p>MyInput</p>
      <input ref={ref} />
    </div>
  );
})

// App.js

import MyInput from './components/MyInput';
import { useRef } from 'react';

...

function App() {
  const myInputRef = useRef();

  const click = () => {
    // 하위 컴포넌트의 ref 가져와 출력
    console.log(myInputRef.current.value);
  }
  
  return <div>
     {/* component에 ref를 지정하여, 상위 컴포넌트에서 하위 컴포넌트의 ref를 연결 할 수 있음*/}
    <MyInput ref={myInputRef} />
    <button onClick={click}>send</button>
  </div>
}

👩🏻 하위 컴포넌트 생성 시 export default forwardRef((props, ref) => {...}) 형태를 사용하며 input 태그 내에 ref를 등록(<input ref={ref} />)하고, 상위 컴포넌트에서 useRef()를 통해 current.value와 같은 값을 사용 가능!

profile
1.5년차 프론트엔드 개발자의 소소한 기록을 담습니다 :-)

0개의 댓글