Skip to content

Instantly share code, notes, and snippets.

@RichardMarks
Last active July 10, 2022 14:39
Show Gist options
  • Save RichardMarks/f941b813e1836f8552aea226d0f90f87 to your computer and use it in GitHub Desktop.
Save RichardMarks/f941b813e1836f8552aea226d0f90f87 to your computer and use it in GitHub Desktop.
React Hooks Toast Example
.toasts-container {
position: fixed;
z-index: 65535;
right: 0;
max-width: 250px;
display: flex;
flex-direction: column-reverse;
}
.toasts-container > .toast-container {
margin-bottom: 10px;
}
.toasts-container:last-child {
margin-bottom: 0;
}
.toast-container {
visibility: hidden;
position: relative;
z-index: 65535;
right: -1000px;
background-color: skyblue;
border: 2px solid black;
border-radius: 10px;
padding: 10px;
max-width: 250px;
}
.toast-container.show-toast {
visibility: visible;
right: 24px;
animation: slidein 0.5s;
}
.toast-container.hide-toast {
visibility: visible;
animation: slideout 0.5s;
}
@keyframes slidein {
from {
right: -1000px;
opacity: 0;
}
to {
right: 24px;
opacity: 1;
}
}
@keyframes slideout {
from {
right: 24px;
opacity: 1;
}
to {
right: -1000px;
opacity: 0;
}
}
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import uuid from "uuid";
import "./styles.css";
const Toast = ({ id, delay = 5500, message, onHide }) => {
const [className, setClassname] = useState("toast-container show-toast");
console.log("render toast");
useEffect(
() => {
console.log("toast set timeout");
let hideTimeout = null;
const timeout = setTimeout(() => {
console.log("toast timeout");
setClassname("toast-container hide-toast");
console.log("hide toast");
hideTimeout = setTimeout(() => {
onHide && onHide(id);
}, 500);
}, delay);
return () => {
console.log("toast clear timeout");
clearTimeout(timeout);
clearTimeout(hideTimeout);
};
},
[id, delay, onHide]
);
return <div className={className}>{message}</div>;
};
const ToastsContainer = ({ toasts, onToastFinished }) => {
return (
<div className="toasts-container">
{toasts.map((toast, index) => (
<Toast key={index} {...toast} onHide={onToastFinished} />
))}
</div>
);
};
function App() {
const [toasts, setToasts] = useState([]);
const showToast = () => {
const toast = {
id: toasts.length,
message: `This is the ${toasts.length + 1} toast message`,
delay: 2500
};
setToasts([...toasts, toast].reverse());
};
const onToastFinished = id => {
setToasts(toasts.filter(toast => toast.id !== id));
};
return (
<div className="App">
<button onClick={showToast}>Show toast</button>
<ToastsContainer toasts={toasts} onToastFinished={onToastFinished} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment