Canovice
Canovice

Reputation: 10173

In React, on button click, display alert for 5 seconds, then hide alert

We are using this CSS which is for an animation where the div (or for any element using the animate class) disappears after 4 seconds.

@keyframes FadeAnimation {
  0% {
    opacity: 1;
    visibility: visible;
  }
  100% {
    opacity: 0;
    visibility: hidden;
  }
}
.animate {
  animation: FadeAnimation 4s ease-in .1s forwards;
}

In react, we have a button that can be clicked, and when the button is clicked, the animate class is added to our Alert div (which was previously hidden):

const [isUpdating, setIsUpdating] = useState(false)
const [showAlert, setShowAlert] = useState(false)
const handleButtonClick = async () => {
    setIsUpdating(true);

    // Axios request to update user info
    try {
        const updateUserObj = { fullName, email };
        const userId = ...;
        const updateResponse = await Axios.put(`/users/update/${userId}`, updateUserObj);
        
        // Set States Following Successful Login
        setIsUpdating(false);
        setShowAlert(true); // setting to true to display hte alert
    } catch (err) {
        setIsUpdating(false);
    }
};

return (
    <Button onClick={handleButtonClick}>
        {`${isUpdating ? 'Updating...' : 'Submit Button'}`}
    />
    <Alert
        className={`modal-alert ${showAlert ? 'animate' : ''}`}
        variant='success'
    >
        Your profile was updated
    </Alert>);
)

This button click handles submitting a form which updates info for a user in our database, and it also displays an alert by updating the showAlert state to true, which adds animate as a class on the alert.

Our problem is that this approach only works for the first click of the button, but not subsequent clicks. When the button is first clicked, showAlert is set to true, and nothing happens that ever turns this back to false. The CSS handles hiding the alert after 4 seconds, but the button is no longer usable.

// Get a hook function
const {useState} = React;

const Example = ({title}) => {
  const [isUpdating, setIsUpdating] = useState(false)
  const [showAlert, setShowAlert] = useState(false)
  const handleButtonClick = () => {
    setIsUpdating(true);
    setIsUpdating(false);
    setShowAlert(true); // setting to true to display hte alert
  };

  let alertClass = showAlert ? 'modal-alert animate' : 'modal-alert';
  let alertStyles = showAlert ? {} : { opacity: 0, visibility: 'hidden', pointerEvents: 'none' };
  return (
    <div>
      <div
        className='submit-button' 
        onClick={handleButtonClick}
      >
        Submit Button
      </div>
      <div
          className={alertClass}
          style={alertStyles}
          variant='success'
      >
          Your profile was updated
      </div>
    </div>
  )
};

// Render it
ReactDOM.render(
  <Example />,
  document.getElementById("react")
);
.modal-alert {
  border: 1px solid #222222;
}

.submit-button {
  cursor: pointer;
  background: blue;
  border-radius: 5px;
  padding: 10px 15px;
  color: white;
  font-size: 1em;
  &:hover {
    background: darkblue;
  }
}

@keyframes FadeAnimation {
  0% {
    opacity: 1;
    visibility: visible;
  }
  100% {
    opacity: 0;
    visibility: hidden;
  }
}
.animate {
  animation: FadeAnimation 4s ease-in .1s forwards;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Upvotes: 1

Views: 4709

Answers (1)

Yevhen Horbunkov
Yevhen Horbunkov

Reputation: 15530

You can make use of onAnimationEnd synthetic event to modify your state back:

<Alert
  className={`modal-alert ${showAlert ? 'animate' : ''}`}
  variant='success'
  onAnimationEnd={() => setShowAlert(false)}
>

Upvotes: 1

Related Questions