-
[react] deepDive 10 Portals(ํฌํ)react 2023. 12. 22. 17:18
๐ฏ Wrapper ๋?
=> ๋ถํ์ํ ์ค์ฒฉ์ ํผํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ํ๊ทธ
Wrapper๋ผ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด์ ๊ฐ์ธ๋ ์ญํ ์ ํ๋ ๊ฒฝ์ฐ์๋ ์๋์ ๊ฐ์ด ๊ฐ๋จํ ํํ๋ก ์์ฑํ ์ ์์
์ด ์ปดํฌ๋ํธ๋ ์์ ์ปดํฌ๋ํธ๋ค์ ๊ฐ์ธ์ ํน์ ํ ์คํ์ผ์ด๋ ๋ ์ด์์์ ์ ์ฉํ ๋ ์ฌ์ฉ๋ ์ ์๋ค
const Wrapper = (props) => { return props.children; }; export default Wrapper;
๐ฏ Fragment ๋?
=> ๊ฐ๊ฒฐํ ์ฝ๋๋ฅผ ์์ฑํ๋๋ฐ ๋์์ฃผ๋ ํ๊ทธ
์ต์ข ํ์ด์ง์ ๋ถํ์ํ HTML์์๋ค์ด ํ์ ๋์ง ์์
๋ฐฉ๋ฒ 1
<> <AddUser onAddUser={addUserHandler} /> <UsersList users={usersList} /> </>;
๋ฐฉ๋ฒ 2
<React.Fragment> <AddUser onAddUser={addUserHandler} /> <UsersList users={usersList} /> </React.Fragment>;
๋ฐฉ๋ฒ 3
import React, { Fragment } from "react"; <Fragment> <AddUser onAddUser={addUserHandler} /> <UsersList users={usersList} /> </Fragment>
<div>ํ๊ทธ ์ผ์๋
<Fragment>ํ๊ทธ ์ผ์ ๋
=> ํ๋ฉด์ <Fragment>ํ๊ทธ์์๊ฐ ๋ํ๋์ง ์์
๐ฏ portal
Portal์ React์์ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ DOM ๊ณ์ธต ๊ตฌ์กฐ์์ ๋ฒ์ด๋ ๋ค๋ฅธ ์์น์ ๋ ๋๋ง๋ ์ ์๊ฒ ํ๋ ๋ฉ์ปค๋์ฆ
React ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ชจ๋ฌ ๋ฑ์ ์ค๋ฒ๋ ์ด ๋๋ ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ฅผ ์ด๋ค ์์น์๋ ๋ ๋๋งํ๋ ค๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋จ=>Portals๋ ํน์ UI ์์๋ฅผ DOM ๊ตฌ์กฐ์์ ๋ถ๋ฆฌํ์ฌ ๋ ๋๋งํ๊ณ ๊ด๋ฆฌํ ์ ์๊ฒ ํด์ฃผ์ด, ๋ ์ ์ฐํ๊ณ ๊ฐ๋ ฅํ UI ํจํด์ ๊ตฌํํ ์ ์์
ํฌํ์ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋๊ฐ์ง๊ฐ ํ์ํจ
๐ช ์ปดํฌ๋ํธ๋ฅผ ์ด๋์ํฌ ์ฅ์
๐ ์ปดํฌ๋ํธ๋ฅผ ์ด๋ํ๊ฒ ๋ค๋ ํ์
1. ์ปดํฌ๋ํธ๋ฅผ ์ด๋์ํฌ ์ฅ์
publicํด๋์ ์ปดํฌ๋ํธ๋ฅผ ์ด๋์ํฌ ์ฅ์๋ฅผ ๋ช ์ํด์ผํจ
<div id="backdrop-root"></div> <div id="overlay-root"></div> <div id="root"></div>
2. ReactDOM.createPortal
๋ฆฌ์กํธ์์ ํฌํ์ ์์ฑํ๋ ๋ฉ์๋
import ReactDOM from "react-dom"; ReactDOM.createPortal(child, container)
- child: ๋ ๋๋งํ React ์์ ๋๋ ์ปดํฌ๋ํธ
- container: child๊ฐ ๋ ๋๋ง๋ ๋์ DOM ๋ ธ๋
import React from "react"; import ReactDOM from "react-dom"; import Card from "./Card"; import Button from "./Button"; import classes from "./ErrorModal.module.css"; 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> ); }; const ErrorModal = (props) => { return ( <React.Fragment> {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") )} </React.Fragment> ); }; export default ErrorModal;
๐ฏ ์ document.getElementById('portal-root') ์ด๋ ๊ฒ ์จ์ฃผ์ด์ผํ ๊น?
{ReactDOM.createPortal( <Backdrop onConfirm={props.onConfirm} />, document.getElementById("backdrop-root") )}
document.getElementById('portal-root')๋
ReactDOM.createPortal์์ ์์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ ๋์ DOM ๋ ธ๋๋ฅผ ์ง์ ํ๋ ์ญํ ์ ํจ.
์๋ํ๋ฉด Portals๋ฅผ ์ฌ์ฉํ ๋, React ์ปดํฌ๋ํธ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ถ๋ชจ ์ปดํฌ๋ํธ์ DOM ๊ณ์ธต ๊ตฌ์กฐ ๋ด์ ๋ ๋๋ง๋์ง๋ง, ReactDOM.createPortal๋ฅผ ์ฌ์ฉํ๋ฉด ํน์ ํ DOM ๋ ธ๋๋ก ์ปดํฌ๋ํธ๋ฅผ ์ด๋์ํฌ ์ ์๋ค
'react' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[react] deepDive 9 ์ปดํฌ๋ํธ ๋ถํ , ์ด๋ฒคํธ ์ฒ๋ฆฌํ๊ธฐ (0) 2023.12.21 [react] deepDive 8 ๋ฆฌ์กํธ ๋๋ฒ๊น (0) 2023.12.20 [react] deepDive 6 ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ์คํ์ผ๋ง (0) 2023.12.20 [react] DeepDive 5 ๋ฆฌ์กํธ state (0) 2023.12.17 [react] DeepDive 4 ๋ฆฌ์กํธ state (0) 2023.12.17