From 780a728f05e792da6c44e60a477e5304e32e66ce Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 26 Aug 2021 17:07:16 -0700 Subject: [PATCH] Improve hiding of UI flash messages (#1728) Use the React hooks for modifying state rather than operating directly on the DOM for hiding of the flash messages. --- .../FlashMessage/FlashMessage.jsx | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/frontend/components/flash_messages/FlashMessage/FlashMessage.jsx b/frontend/components/flash_messages/FlashMessage/FlashMessage.jsx index 8e193789ba..4739900ba0 100644 --- a/frontend/components/flash_messages/FlashMessage/FlashMessage.jsx +++ b/frontend/components/flash_messages/FlashMessage/FlashMessage.jsx @@ -1,7 +1,6 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import PropTypes from "prop-types"; import classnames from "classnames"; -import { connect } from "react-redux"; import notificationInterface from "interfaces/notification"; import FleetIcon from "components/icons/FleetIcon"; @@ -22,26 +21,27 @@ const FlashMessage = ({ [`${baseClass}--full-width`]: fullWidth, }); - useEffect(() => { - if (alertType === "success" && isVisible) { - setTimeout(() => { - const elt = document.getElementById(`${klass}`); - if (!elt) { - return; - } - elt.style.visibility = "visible"; - }, 0); // Ensures successive, success alerts are visible - setTimeout(() => { - const elt = document.getElementById(`${klass}`); - if (!elt) { - return; - } - elt.style.visibility = "hidden"; - }, 4000); // Hides success alerts after 4 seconds - } - }); + const [hide, setHide] = useState(false); - if (!isVisible) { + // This useEffect handles hiding successful flash messages after a 4s timeout. By putting the + // notification in the dependency array, we can properly reset whenever a new flash message comes through. + useEffect(() => { + // Any time this hook runs, we reset the hide to false (so that subsequent messages that will be + // using this same component instance will be visible). + setHide(false); + + if (alertType === "success" && isVisible) { + // After 4 seconds, set hide to true. + const timer = setTimeout(() => setHide(true), 4000); + // Return a cleanup function that will clear this reset, in case another render happens + // after this. We want that render to set a new timeout (if needed). + return () => clearTimeout(timer); + } + + return undefined; // No cleanup when we don't set a timeout. + }, [notification, alertType, isVisible, setHide]); + + if (hide || !isVisible) { return false; }