¿Alguien puede decirme por qué usamos if (ref.current && !ref.current.contains(event.target)) en lugar de 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]); }Entonces, el problema principal es que es posible que la referencia no se establezca en el primer renderizado. Se garantizó que se configuraría en componentDidMount, cuando usamos clases, por ejemplo, pero en componentes funcionales es un poco más complicado, ya que no tenemos ciclos de vida y tenemos efectos, por lo que es útil verificar, si se establece ese valor de referencia.
De acuerdo con los documentos
Cuando se pasa una
refa un elemento en el renderizado, se puede acceder a una referencia al nodo en el atributocurrentde la referencia.
ref en sí mismo puede tener un valor, pero para acceder al elemento, debe usar ref.current , que puede no estar definido.
Para acortar su sintaxis, puede usar el encadenamiento opcional
if (!ref.current?.contains(event.target) { // ... }La propiedad .current puede ser nula, por lo que solo debemos asegurarnos de que la propiedad no sea nula antes de intentar leer la propiedad .current. Recuerde que .current se establece después de que la función regrese.