I am using the React MUI library with NextJS
I am trying to create a function where snackbars generated are stored in an array within the store (using a redux like library called Easy-Peasy) and then shown one by one as they timeout.
E.g. if there are 3 snackbars due to three errors the user made - then:
First snackbar will show - then timeout after 4 seconds
Second will show and then a 4 second time out
Third will show and then time out after 4 seconds
If one snackbar is generated then it will work normally, i.e. disappear once it times out.
If there are two or more snackbars, then it will cause only one to disappear leaving behind n-1 snackbars, e.g. if there are 3 in the array, one will disappear leaving two in the queue. The second one will never disappear via timeout.
import { useState, useEffect } from 'react'
import { Snackbar, Alert } from '@mui/material'
export default function SnackBar(props) {
const snackbarData = []
// this will be an array from the store which is structured:
// [
// { id: 1, message: 'message1', severity: 'error' },
// { id: 2, message: 'message2', severity: 'error' }
// ]
const removeSnackbarMessage = () => {
// a function which performs a .shift() method on the snackbarData array within the store
}
const [open, setOpen] = useState(false)
const [message, setMessage] = useState('')
const [severity, setSeverity] = useState('')
const handleClose = (event, reason) => {
if (reason === 'clickaway') { return }
setOpen(false)
removeSnackbarMessage()
}
useEffect(() => {
if (snackbarData.length > 0) {
setOpen(true)
setMessage(snackbarData[snackbarData.length - 1].message)
setSeverity(snackbarData[snackbarData.length - 1].severity)
} else {
setOpen(false)
setMessage('')
setSeverity('')
}
}, [snackbarData, snackbarData.length])
return (
<Snackbar
open={open}
autoHideDuration={4000}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom'}}
onClose={handleClose}
>
<Alert severity={severity}>{message}</Alert>
</Snackbar>
)
}
Above is the code that is contained within the <SnackBar /> component, which is referenced within index.js.
Any help is appreciated. TIA.
The issue is the messages you want to "queue" are just overwriting the single message stored in state. You need to create a queue (array) of messages but cannot use the default
autoHideDurationproperty in this case because that's only meant for a single message.Here's a working example of a queued Snackbar notification system using React18 and MUI which you can tie-into a store.
index.js
App.js
Snackbar.js
package.json
Working CodeSandbox:
https://codesandbox.io/p/sandbox/react18-mui5-queued-snackbar-messages-k9v6rw
Expected Functionality:
Initially, it will load 3 messages and play through them, 4-seconds at a time. You can also queue up more messages by simply clicking the button.
I hope that helps!