728x90
728x90
토스트 메시지 띄우기 간단 예제 (ReactDOM.createPortal)
들어가며
- 리액트(React.js)를 이용하여 구현해본 토스트(Toast) 메시지 띄우기 간단 예제 코드를 올려본다.
- 기능을 구현하기 위해 @react-dom@ 패키지의 @createPortal@ 함수를 사용하였다.
코드
App.jsx
import React from 'react';
import Toast from './Toast';
function App() {
const [isToastVisible, setIsToastVisible] = React.useState(false);
function handleEnrol() {
setIsToastVisible(true);
setTimeout(() => {
setIsToastVisible(false);
}, 3000);
}
return (
<div id="app">
{ isToastVisible && <Toast message={"You are enrolled successfully! :)"} /> }
<article>
<h2>React Course</h2>
<p>
A course that teaches you React from the ground up and in great depth!
</p>
<button onClick={handleEnrol}>Enrol</button>
</article>
</div>
);
}
export default App;
Toast.jsx
- @react-dom@ 패키지에 있는 @createPortal(content, target)@ 함수는 @index.html@ 파일에 있는 @target@ 요소에 현재 컴포넌트를 반환해준다.
- 현재 토스트 메시지 컴포넌트가 부모 컴포넌트(@App.jsx@)의 자식 컴포넌트로 있지만, 이 기능을 이용할 경우 @App.jsx@와 동일한 위치로 옮길 수 있다.
- 아래의 코드에는 @index.html@ 코드의 @<body>@ 요소에 @Toast@ 컴포넌트를 위치시킨다.
import ReactDOM from "react-dom";
export default function Toast({ message }) {
return ReactDOM.createPortal(
<aside className="toast" data-testid="toast">
<p>{message}</p>
</aside>,
document.querySelector('body')
);
}
index.css
@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@400;700&family=Lato:wght@400;700&display=swap');
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Raleway', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background: linear-gradient(#180d27, #0c0219);
color: #e5d9f1;
min-height: 100vh;
}
#app {
margin: 2rem auto;
padding: 1rem;
max-width: 30rem;
text-align: center;
border-radius: 6px;
background: linear-gradient(#341a89, #3a1967);
box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
}
button {
margin: 0.5rem;
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
background: #e5d9f1;
color: #341a89;
font-family: 'Lato', sans-serif;
font-size: 1rem;
font-weight: 700;
cursor: pointer;
transition: all 0.2s ease-out;
}
.toast {
position: absolute;
top: 2rem;
left: 3rem;
padding: 1rem;
border-radius: 4px;
background: rgba(118, 234, 189, 0.8);
color: black;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
animation: fade-slide-in-from-left 0.3s ease-out;
}
.toast p {
margin: 0;
}
@keyframes fade-slide-in-from-left {
0% {
opacity: 0;
transform: translateX(-1rem);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Toast Message Example</title>
</head>
<body>
<div id="content">
<div id="root"></div>
</div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
참고 사이트
728x90
728x90
'Programming > React' 카테고리의 다른 글
[React.js] memo() 사용할 때 주의할 점 (0) | 2024.06.25 |
---|---|
[React.js] useEffect와 useCallback (0) | 2024.06.24 |
[React.js] useReducer 훅 (0) | 2024.06.07 |
[React.js] map 함수를 사용할 때 중괄호({})와 소괄호(()) (0) | 2024.05.29 |
[React.js] useImperativeHandle과 forwardRef (0) | 2024.05.21 |
[React.js] 부모 컴포넌트에서 자식 컴포넌트로 요소 넘기는 방법 (0) | 2024.05.14 |
[React.js] 실시간으로 특정 요소의 길이값 가져오기 (0) | 2024.03.26 |
[React.js] state와 ref 비교하기 (0) | 2024.03.02 |