--- title: Closable alert tags: components,state,effect cover: flower-portrait-1 firstSeen: 2019-09-17T13:19:30+03:00 lastUpdated: 2021-01-07T23:57:13+02:00 --- Renders an alert component with `type` prop. - Use the `useState()` hook to create the `isShown` and `isLeaving` state variables and set both to `false` initially. - Define `timeoutId` to keep the timer instance for clearing on component unmount. - Use the `useEffect()` hook to update the value of `isShown` to `true` and clear the interval by using `timeoutId` when the component is unmounted. - Define a `closeAlert` function to set the component as removed from the DOM by displaying a fading out animation and set `isShown` to `false` via `setTimeout()`. ```css @keyframes leave { 0% { opacity: 1 } 100% { opacity: 0 } } .alert { padding: 0.75rem 0.5rem; margin-bottom: 0.5rem; text-align: left; padding-right: 40px; border-radius: 4px; font-size: 16px; position: relative; } .alert.warning { color: #856404; background-color: #fff3cd; border-color: #ffeeba; } .alert.error { color: #721c24; background-color: #f8d7da; border-color: #f5c6cb; } .alert.leaving { animation: leave 0.5s forwards; } .alert .close { position: absolute; top: 0; right: 0; padding: 0 0.75rem; color: #333; border: 0; height: 100%; cursor: pointer; background: none; font-weight: 600; font-size: 16px; } .alert .close::after { content: 'x'; } ``` ```jsx const Alert = ({ isDefaultShown = false, timeout = 250, type, message }) => { const [isShown, setIsShown] = React.useState(isDefaultShown); const [isLeaving, setIsLeaving] = React.useState(false); let timeoutId = null; React.useEffect(() => { setIsShown(true); return () => { clearTimeout(timeoutId); }; }, [isDefaultShown, timeout, timeoutId]); const closeAlert = () => { setIsLeaving(true); timeoutId = setTimeout(() => { setIsLeaving(false); setIsShown(false); }, timeout); }; return ( isShown && (
) ); }; ``` ```jsx ReactDOM.render( , document.getElementById('root') ); ```