JSX? JS๋ฅผ ์๋ฏธํ๋ ๊ฑด๊ฐ? ๋ค์ x๊ณผ ๋ถ์ ๊ฑด ๋ฌด์จ ์๋ฏธ์ผ๊น ๊ถ๊ธํด์ง๋ค.
portals์ react์์ ์ด๋ป๊ฒ ์ฐ์ด๊ณ ์๋ ๊ฑธ๊น? ์ค๋์ ๊ณต๋ถ ์ฃผ์ ๋ค์ ํฅ๋ฏธ๋กญ๋ค.
์์๋ฅผ ํ์ตํ๋ฉฐ ๊ณต๋ถํด๋ณด๋๋ก ํ์.
const App = () => {
const [loading, setLoading] = useState(true);
const [lang, setLang] = useState('ko')
// ์กฐ๊ฑด๋ฌธ
if(loading) return <div>Loading....</div>;
return (
<div>
// return๋ฌธ ์์์๋ ์ผํญ ๋๋ ๋
ผ๋ฆฌ ์ฐ์ฐ์
{lang === 'ko'? '์๋
ํ์ธ์': 'Hello world'};
// ์์์ ๊ฐ์ง ์์ผ๋ฏ๋ก ๋ซ๋ ํ๊ทธ ์ฌ์ฉ
<input type="text"/>
</div>
)
}
๐ง JSX๋ ํ๋์ root๋ก ๊ฐ์ธ์ ธ์ผ ๋๋ ์ด์ ?
React.createElement๋ฅผ ํธ์ถํ ๋ ๊ธฐ์ ์ ์ผ๋ก ํ๋์ root๋ง ํ์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ ์์์ div๊ฐ root๋ฅผ ์๋ฏธํ๋ค.React.createElement('div', null, 'Hello');
return๋ฌธ ์์์ ํ๋์ root๋ก ๊ฐ์ธ์ ธ์ผ ๋๋ ๊ธฐ์ ์ ์ธ ์๊ตฌ๋ก ์ธํด react ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ณด๋ฉด ์๋ง์ div๊ฐ ์ค์ฒฉ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ์ด๋ฅผ div soup๋ผ๊ณ ํ๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ฐฉ๋ฒ๋ค์ ์๋์ ๊ฐ๋ค.
// Wrapper.jsx
const Wrapper = (props) => {
return props.children;
}
// App.jsx
const App = () => {
return (
<Wrapper>
<Item />
<Item />
</Wrapper>
)
}
<></>
๋ก๋ Fragment๋ฅผ ํํํ ์ ์์.const App = () => {
return (
<Fragment>
<Item />
<Item />
</Fragment>
)
}
์ฌ์ ์ ์ผ๋ก ๋ ๊ฐ์ ์๋ก ๋ค๋ฅธ ์์น๋ฅผ ์ฐ๊ฒฐํ๋ ๋ง๋ฒ์ด๋ ๊ธฐ์ ์ ์ธ ๋ฌธ์ด๋ผ๋ ์๋ฏธ๋ฅผ ๊ฐ์ง๊ณ ์๋ค. ์ด ๋ป ๊ทธ๋๋ก Portals์ react์์ ๋ค๋ฅธ DOM ๋ ธ๋๋ก ์์๋ฅผ ๋ ๋๋งํ ์ ์๋๋ก ํด์ค๋ค. Portals ์ฐ์ง ์์๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ง๋ง ์ ๊ทผ์ฑ ์ธก๋ฉด์์๋ ์๋ฉํฑ ๊ด์ ์์๋ ์ข์ง ์๊ธฐ ๋๋ฌธ์ ์ด ์ ์ ๊ณ ๋ คํด์ ์ฌ์ฉํด์ผ ํ๋ค.
๐์์ ๊ฐ๋ ์ ๊ฐ์ฅ ์ ์ ์ฉํ ์ ์๋ ๊ฒ์ Modal๋ก ์์๋ฅผ ํตํด ์์๋ณด์.
<!--index.html-->
<body>
<div id="modal__root"></div> <!--๋ชจ๋ฌ์ด ๋ค์ด๊ฐ๋ root-->
<div id="root"></div>
</body>
React.createPortal(์ ๋ฌํ ์ปดํฌ๋ํธ, ์ปจํ
์ด๋๊ฐ ๋๋ DOM ๋
ธ๋)
// Modal.jsx
const Modal = props => {
return (
<>
<div className="dimmed__layer" onClick={props.onConfirm}></div>
<div className="modal__body">{props.title}</div>
</>
)
}
const WarningModal = props => {
return (
<>
{React.createPortal(<Modal title={props.title} onConfirm={props.onConfirm}/>, document.querySelector('#modal__root'))}
</>
)
}
// App.jsx
const App = () => {
const [isShowModal, setIsShowModal] = useState(false);
const onConfirm = () => setIsShowModal(false);
return (
<>
{isShowModal && <WarningModal title="warning" onConfirm={onConfirm}/>}
<Item />
<Item />
</>
)
}
react๋ฅผ ๊ณต๋ถํ๋ฉด์ ์ปดํฌ๋ํธํ์ ๋ ์ง์คํ๋ ๊ฒฝํฅ์ด ์์๋ค. ๊ทธ๋ฌ๋ค๋ณด๋ ์ ๊ทผ์ฑ๊ณผ ์๋ฉํฑ ๋งํฌ์ ์ ๋ํด ์ ๊ฒฝ์ฐ์ง ๋ชปํ๊ณ ์ ๋๋ก ์๋ฏธ๋ฅผ ๊ฐ๋๋ก ๋งํฌ์ ํ๋ ๊ฒ์ด ์ด๋ ค์ ๋ค. ์ด๋ฐ ๋ฌธ์ ์ ๋ค์ createPortal์ด๋ผ๋ ๊ฒ์ ํตํด์ ํ๋ฒ์ ํด๊ฒฐํ ์ ์๋ค๋ ์ ์ธ๊ณ์๋ค. Modal์ ๋ฐ๋ณตํ์ตํ๋ฉด์ portal์ ๋ํด ์ต์ํด์ง๊ณ ์๋ฉํฑ ๋งํฌ์ ์ ์ํด ๋ ๊น๊ฒ ์๊ฐ์ ํด์ผ๊ฒ ๋ค.
์ฐธ๊ณ ์๋ฃ
https://ko.reactjs.org/docs/portals.html