Reputation: 319
I have a toast notification created using react-bootstrap. I need to dismiss it if the user clicks anywhere outside the toast. Someone knows how can I do that?
This is the toast I'm using:
//what am I importing
import { Toast } from 'react-bootstrap';
//how am I using it
<Toast
onClose={() => props.OnClose(false)}
data-testid="toast"
show={props.Show}
delay={10000}
autohide
>
<Toast.Header closeButton={false}>
<div>
{props.Icon}
</div>
<div>
Title
</div>
<div
onClick={() => props.OnClose(false)}
>
<ToastClose />
</div>
</Toast.Header>
<Toast.Body>
Body text
</Toast.Body>
</Toast>
Upvotes: 1
Views: 2516
Reputation: 260
What you can use is React hook useRef
. Using useRef hook we can access the DOM elements easily and in this case we are accessing the Toast component and tracking clicks that happen outside of the component and firing the setShow(false)
to update the state and dismiss the Toast component. This code will dismiss the Toast if the user clicks anywhere outside of it:
import { Toast } from "react-bootstrap";
import { useState, useRef, useEffect } from "react";
export default function App() {
const [show, setShow] = useState(true);
function useOutsideAlerter(ref) {
useEffect(() => {
/**
* Close toast if clicked on outside of element
*/
function handleClickOutside(event) {
if (ref.current && !ref.current.contains(event.target)) {
setShow(false);
}
}
// Bind the event listener
document.addEventListener("mousedown", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener("mousedown", handleClickOutside);
};
}, [ref]);
}
const wrapperRef = useRef(null);
useOutsideAlerter(wrapperRef);
return (
<div className="App">
<Toast
onClose={() => setShow(false)}
data-testid="toast"
show={show}
delay={10000}
autohide
ref={wrapperRef}
>
<Toast.Header closeButton={false}>
<div>Toast title</div>
<div onClick={() => setShow(false)}>Close button</div>
</Toast.Header>
<Toast.Body>Body text</Toast.Body>
</Toast>
</div>
);
}
Original post with more info: link
Upvotes: 2