I have this small project I wrote in javascript and I’m trying to rewrite it using React. I have an Alert section where I prepend a message to so it appears at the top of the list, then gets removed after 5 seconds.
HTML:
<div id="alert-container">
<button onclick="addAlert('alert')">Add</button>
</div>
JS:
function addAlert(message) {
const alertContainer = document.getElementById("alert-container")
const alert = document.createElement("div")
alert.textContent = message
alertContainer.prepend(alert)
setTimeout(() => {
alert.remove()
}, 5000)
}
Where I’m stuck is I don’t know how to "prepend" a React element. I could create a state that has a list of alert messages and then add a new for every one of those, but I’m hit with two issues:
-
How to I set a timer to remove the actual React element after 5 seconds
-
How do I remove the message from the list of messages once it’s time for it to be removed? I suppose I could add a
show:true
attribute and then set it tofalse
after the timeout runs for each alert , but I am not sure if that is the ideal way to do this as it seems slightly over complicated.
I feel like this should be relatively simple to do like in the JS I have above, but I can’t really find a simple way to do this. Any pointers?
Thanks!
>Solution :
Where I’m stuck is I don’t know how to "prepend" a React element. I could create a state that has a list of alert messages and then add a new for every one of those
Yes, that’s the way you’d do it. You’ll have an array as your state, and then to prepend a new alert, you’ll add to the front of that array.
How to I set a timer to remove the actual React element after 5 seconds
You can set the timeout right after you make the change to the array
How do I remove the message from the list of messages once it’s time for it to be removed?
When the timer goes off, you’ll set state and remove the alert from the array. Assuming the timers are all exactly 5 seconds your alert will have moved to the end of the array, so you can just remove the last element in the array.
import { useState } from 'react';
const AlertContainer = () => {
const [alerts, setAlerts] = useState([]);
const addAlert = (message) => {
setAlerts(prev => [message, ...prev]);
setTimeout(() => {
setAlerts(prev => {
const next = [...prev];
next.pop();
return next;
});
}, 5000);
}
return (
<div>
{alerts.map((message, i) => (
<div key={i}>{message}</div>
))}
<button onClick={() => addAlert('alert')}>Add</button>
</div>
)
}