can anyone tell me why we use if (ref.current && !ref.current.contains(event.target)) instead of if (!ref.current.contains(event.target))
function useOutsideAlerter(ref) {
useEffect(() => {
// Function for click event
function handleOutsideClick(event) {
if (ref.current && !ref.current.contains(event.target)) {
alert("you just clicked outside of box!");
}
}
// Adding click event listener
document.addEventListener("click", handleOutsideClick);
return () => document.removeEventListener("click", handleOutsideClick);
}, [ref]);
}
CodePudding user response:
The property .current can be null, so e just have to safe guard that the property is Not null before trying to read the .current property. Remember .current is set after the function returns.
CodePudding user response:
So main issue is that ref may not be set on first render. It was guarantied to be set in componentDidMount, when we used classes for example, but in functional components it's a little bit more tricky, since we don't have such thing as lifecycles and we have an effects, so it's useful to check, if that ref value is set.
CodePudding user response:
because current can be undefined..but you can do !ref.current?.contains()
.
CodePudding user response:
According to the docs
When a
ref
is passed to an element in render, a reference to the node becomes accessible at thecurrent
attribute of the ref.
ref
itself might have a value, but to access the element you need to use ref.current
which can be undefined.
To make your syntax shorter you can use Optional chaining
if (!ref.current?.contains(event.target) {
// ...
}