So for my use case, I need to monitor when a user leaves the application and based on that give a warning and change the contents of the application so the user can't cheat. That being said this is how I was able to solve it based on @TheZanke Approach
Wrap the component you need to have this functionality around and pass the props in and should work perfectly. maintaining this is way easier for my case so I use this
import PropTypes from "prop-types"
import React, { useState, useEffect } from 'react'
export default function OutsideAlerter({ children, fallback, initialIsVisible, isVisible, onSetIsVisible }) {
const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible);
const handleClickOutside = event => {
if (!event?.currentTarget?.contains(event?.relatedTarget)) {
onSetIsVisible(false)
}
};
const handleClickInside = event => {};
useEffect(() => {
setIsComponentVisible(isVisible === undefined ? initialIsVisible : isVisible);
}, [isVisible])
return (
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
}}
tabIndex="0"
onBlur={handleClickOutside}
onClick={handleClickInside}
>
{isComponentVisible ? children : fallback}
</div>
)
}
OutsideAlerter.propTypes = {
children: PropTypes.element,
fallback: PropTypes.element,
initialIsVisible: PropTypes.bool.isRequired,
isVisible: PropTypes.bool,
onSetIsVisible: PropTypes.func
}
This is the fallback component passed

<OutsideAlerter
fallback={
<div style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
color: '#fff',
alignItems: 'center',
height: '100vh',
}}>
<div>You have clicked outside of the application</div>
<button
name='exam'
onClick={(e) => handleVisible(e, true)}
>IsVisible</button>
</div>
}
initialIsVisible={true}
isVisible={isVisible?.exam}
onSetIsVisible={(e) => handleVisible({ target: { name: 'exam' } }, e)}
>
<BaseRoutes />
</OutsideAlerter>
const handleVisible = (e, bool) => {
setIsVisible({ ...isVisible, [e.target.name]: bool })
}