i'm working on a continuous notification (every 3 seconds and max 1 min), until user accept pending orders.
This is my code. usePrevious is custom hook that gives me previous value of state.
I don't mind why, when setTimeout executes clearInterval(), 'notification' is null. This problem cause loop in sound.
[.....]
const [notification, setNotification] = useState(null)
const previousOrderCount = usePrevious(newOrderCount)
const previousPendingReservationsLength = usePrevious(
pendingReservationsLength
)
const isToneActive = useRef(false)
// sound notify for new orders
useEffect(() => {
if (
!isToneActive.current &&
newOrderCount > previousOrderCount &&
user?.profile?.role === "manager"
) {
// this prevent multiple triggers of sound
isToneActive.current = true
setNotification(setInterval(() => playNotification(), 3000))
setTimeout(() => {
clearInterval(notification)
isToneActive.current = false
}, 60000)
}
}, [
newOrderCount,
playNotification,
user,
previousOrderCount,
stopNotify,
notification,
setNotification,
])
[....]
I would use another React ref to hold a reference to the interval timer. The issue here is that React state updates are asynchronous, so the setNotification
state update doesn't immediately update the notification
state for the setTimeout
callback that encloses the current null
state value.
const notificationRef = React.useRef(null);
...
notificationRef.current = setInterval(() => playNotification(), 3000);
setTimeout(() => {
clearInterval(notificationRef.current);
notificationRef.current = null;
isToneActive.current = false;
}, 60000);