I have this reusable component in my react app.
export const OutsideWrapper = ({ children, onOutside, className }) => {
const wrapperRef = useRef(null);
const [style, setStyles] = useState({
opacity: 1
});
useEffect(() => {
console.log("1. component was mounted");
const i = e => {
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
console.log("3. outside click was trigerred");
e.preventDefault();
setStyles({ opacity: 0 });
setTimeout(() => {
onOutside();
}, 100);
}
};
window.addEventListener("click", i, true);
console.log('2. listener was added');
return () => {
console.log("4. listerner was removed");
window.removeEventListener("click", i, true);
};
}, [onOutside]);
return (
<div
ref={wrapperRef}
style={style}
className={`outside-wrapper ${className}`}
>
{children}
</div>
);
};
When this OutsideWrapper component get's rendered, it should add event listener to the document, then listen to an event, call onOutside function and then unmount. (onOutside unmounts the component). After that listener gets removed.
But when component get's rendered, it immediately calls onOutside and unmounts.
Here's the part of parent component:
const [down, setDown] = useState(false);
return (
<input onFocus={()=>setDown(true)}/>
{down && (
<OutsideWrapper
onOutside={() => setDown(false)}
className="input-wrapper"
>
<DropDownList
items={dropDownItems}
term={data.location}
onChoose={onChoose}
/>
</OutsideWrapper>
)}
)