diff --git a/src/components/NotificationHandler.js b/src/components/NotificationHandler.js index 743870987..98a6bed78 100644 --- a/src/components/NotificationHandler.js +++ b/src/components/NotificationHandler.js @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { @@ -26,32 +26,39 @@ export default function NotificationHandler() { const notificationsToDisplay = useSelector(selectNotificationsToDisplay); const notificationsWithSound = useSelector(selectNotificationsWithSound); + const hasNotifications = useMemo( + () => + notificationsToDisplay.length > 0 || notificationsWithSound.length > 0, + [notificationsToDisplay, notificationsWithSound], + ); + + const hasNotificationsWithSound = useMemo( + () => notificationsWithSound.length > 0, + [notificationsWithSound], + ); + const dispatch = useDispatch(); useEffect(() => { - if ( - notificationsToDisplay.length > 0 || - notificationsWithSound.length > 0 - ) { + // use memoized value to avoid re-setting timeout when more notifications arrive + if (hasNotifications) { setTimeout(() => { dispatch(clearNotifications()); }, NOTIFICATION_DURATION_MS); } - }, [notificationsToDisplay, notificationsWithSound, dispatch]); + }, [hasNotifications, dispatch]); useEffect(() => { // on Android, when notification is received, OS let us execute some code // but it's very limited, e.g. handlers set via setTimeout are not executed // so we do not play sound in that case, because we will not be able to stop it - if ( - notificationsWithSound.length > 0 && - AppState.currentState === 'active' - ) { + // use memoized value to avoid re-starting the sound when more notifications arrive + if (hasNotificationsWithSound && AppState.currentState === 'active') { dispatch(startSound()); } else { dispatch(stopSound()); } - }, [notificationsWithSound, dispatch]); + }, [hasNotificationsWithSound, dispatch]); return (