Here is my notification component.
Notification.js
const Notification = (props) => {
const [dNone, setdNone] = useState(false);
useEffect(() => {
const timeout = setTimeout(() => {
setdNone(true);
}, 4000);
return () => {
clearTimeout(timeout);
};
}, []);
return (
// type
// 1 : error-alert
// 2 : warning-alert
// 3 : info-alert
// 4 : success-alert
<div className={`custom-alert ${props.type} ${dNone ? "d-none" : ""}`}>
<span className="bi bi-x-circle-fill error-icon-alert"></span>
<div>
<p className="mb-0 pb-0 custom-alert-desc">{props.msg}</p>
</div>
</div>
);
};
UseNotificationManager.js
function UseNotificationManager(List, type) {
return List.map((item) => {
return <Notification type={type} msg={item.msg} />;
});
}
here List is a list of the message strings.
This work fine, the notification is removed after 4 seconds, if there is more than 1 message there will be two notification and they will be removed in the manner they were added. when I add a new notification only a new message will be added to the existing notification that is not removed yet.
Problem is when i pass key prop in
all the notification is removed at once and when I add a new notification it also displays all old message with new one and all are removed at the same time.
I don’t know why that is happening.
I expect that if I add a notification it displayed when I add a second notification after a 3-second message is added to the existing one. The first notification should disappear after 3+1 = 4 seconds even If I pass the key prop to .
here is the reproducible code.
https://codesandbox.io/s/infallible-bird-nk0oj0?file=/src/UseNotificationManager.js:230-243
>Solution :
Your CodeSandbox example passes in a key that changes for every render, causing React to always unmount and remount the component. That’s arguably worse than passing in no key. The key should be specific to the item rendered, and not change.
In other words, generate an unique ID for the data, e.g.
setNotificationList((prev) => [
...prev,
{ id: uuid(), msg: "Something went wrong..........!" }
]);
and use it as the key when rendering notifications (I renamed the component here since the convention is that things that start with use are hooks):
function NotificationManager(notificationList, type) {
return notificationList.map((item) => {
return <Notification type={type} key={item.id} msg={item.msg} />;
});
}