<div id="app"></app>
.outside {
width: 100vw;
height: 100vh;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
}
.content {
width: 200px;
height: 200px;
background-color: teal;
margin: auto;
display: flex;
align-items: center;
justify-content: center;
}
const { useRef, useEffect, useState } = React;
function OutsideWrapper() {
return (
<div className="outside">
<Content />
</div>
);
}
function Content() {
const [clicked, setClicked] = useState(false);
const ref = useRef(null);
useOutsideClickDetector(ref, () => {
setClicked(false);
});
return (
<div className="content" onClick={() => setClicked(true)} ref={ref}>
{clicked ? "Click Outside" : "Click Me"}
</div>
);
}
function useOutsideClickDetector(
ref: React.RefObject<Node>,
handler: (event: MouseEvent) => void
) {
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (ref.current && !ref.current.contains(event.target as Node)) {
handler(event);
}
}
document.addEventListener("click", handleClickOutside);
return () => {
document.removeEventListener("click", handleClickOutside);
};
}, [ref]);
}
ReactDOM.render(<OutsideWrapper />, document.getElementById("app"));
View Compiled
This Pen doesn't use any external CSS resources.