React 관련 강의 영상을 보고 정리한 내용
Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 최고의 방법을 제공
ThankyouDialog.jsx
import React from 'react'
import Dialog from './Dialog'
export default function ThankyouDialog() {
return (
<div>
<Dialog title={<h1 style={{
color:"purple"
}}> Thanks</h1>} description="It is honor to meet you" button={<button style={{backgroundColor:"blue", color:"white"}}>close</button>}>
</Dialog>
</div>
)
}
Dialog.jsx
import React, { useState } from 'react'
export default function Dialog(props) {
const [isOpen,setIsOpen] = useState(false);
return (
<div>
<button onClick={()=>setIsOpen(true)}>Open</button>
{isOpen && <div
style={{
position:"absolute",
zIndex:99,
top:"50%",
left:"50%",
transform:"translate(-50%,-50%)",
border:"1px solid black",
padding:24,
backgroundColor:"white",
}}>
{typeof props.title === "string" ? (<h1>{props.title}</h1>) : props.title}
{typeof props.description === "string" ? (<h5>{props.description}</h5>) : props.description}
{typeof props.button === "string" ? (<button style={{backgroundColor:"red", color:"white"}} onClick={() => setIsOpen(false)}>{props.button}</button>) : <div onClick={()=>setIsOpen(false)}>{props.button}</div>}
</div>
}
{isOpen && <div style={{
position:"fixed",
top:0,
left:0,
bottom:0,
right:0,
backgroundColor:"lightgray"
}}>
</div>}
</div>
)
}
Example.jsx
import React from 'react'
import ThankyouDialog from './ThankyouDialog'
export default function Example() {
return (
<div>
<ThankyouDialog/>
<div style={{position:'absolute'}}>
<button>하하하하하</button>
</div>
</div>
)
}
Dialog를 z-index를 주어 띄워지게 만들어 놧지만 위 코드를 실행시에는 button이 가려지지 않고 모달창이 따로 나타난다.
import React from 'react'
import ThankyouDialog from './ThankyouDialog'
export default function Example() {
return (
<div>
<div style={{position:'absolute'}}>
<button>하하하하하</button>
</div>
<ThankyouDialog/>
</div>
)
}
하지만 ThankyouDialog
코드를 아래로 내리면 버튼이 안보이는 걸 알 수 있다.
현재는 하나의 부모 컴포넌트 안에서 가지고 있어 위치를 내가 임의로 바꾸어서 조정할 수 있지만 어느 컴포넌트에 n번째 자식을 가지고 있다면 순차적으로 가지고 있는 UI의 스택을 벗어날 수 없게 된다.
다시 아까처럼 ThankyouDialog
코드를 위에 올린 다음
public 폴더 안에 있는 index.html파일안으로 가서
<div id="portal"></div>
을 생성
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="portal"></div>
Example.jsx 아래와같이 수정
import React from 'react'
import { createPortal } from 'react-dom'
import ThankyouDialog from './ThankyouDialog'
const Protal = (props) =>{
return createPortal(props.children, document.getElementById('portal'))
}
export default function Example() {
return (
<div>
<ThankyouDialog/>
<div style={{position:'absolute'}}>
<button>하하하하하</button>
</div>
</div>
)
}
Open이라는 버튼이 '하하하하' 버튼으로 인해 가려지기 때문에 Open 버튼에 css를 추가
Dalog.jsx
<button style={{position:'absolute',left:100}} onClick={()=>setIsOpen(true)}>Open</button>
이런 행위 들로 인해 portal라는 div 태그가 root태그의 stack을 넣어나 최상위가 되어 오픈 버튼 클릭 시 '하하하하' 버튼을 가리게 된다.