Estoy usando un React Hook para detectar cuándo un elemento está visible en la ventana gráfica. Hasta entonces, todo funciona bien, pero necesito "restablecer" el estado cuando todo está oculto (como llegar al pie de página o al encabezado).
Aquí está mi anzuelo:
import { useState, useEffect, useRef } from 'react' const useIntersect = (ref) => { const [isOnScreen, setIsOnScreen] = useState(false) const observerRef = useRef(null) useEffect(() => { observerRef.current = new IntersectionObserver(([entry]) => { setIsOnScreen(entry.isIntersecting) }) }, []) useEffect(() => { observerRef.current.observe(ref.current) return () => observerRef.current.disconnect() }, [ref]) return isOnScreen } export default useIntersectY aquí está el estado que estoy actualizando:
const elementRef = useRef(null) const[state, setState] = useState('nothing is visible') const onScreen = useIntersect(elementRef) useEffect(() => { return onScreen ? setState('an item is visible') : null }) return ( <Item ref={elementRef}> ... </Item> ) Necesito poder decir setState('...') a algo (digamos una cadena) cuando todos los elementos están fuera de la ventana gráfica (cuando no se cumple la condición onScreen) pero incluso cuando llego al pie de página cuando no hay nada visible, mantiene el último elemento en la memoria.
He intentado muchas cosas pero no puedo encontrar una salida :(
¡Gracias por la ayuda!
Su implementación de gancho parece estar bien. es posible que desee volver a comprobar la altura del componente Item . verifique que este código sandbox funcione bien con su implementación de gancho: https://codesandbox.io/s/elegant-wood-ruks2?file=/src/App.js
Creo que su useIntersect debería agregar una dependencia en ref.current en lugar de ref para el segundo useEffect
asi que
useEffect(() => { observerRef.current.observe(ref.current) return () => observerRef.current.disconnect() }, [ref.current]);y luego, cuando lo use en el componente, haga
useEffect(() => { return onScreen ? setState('an item is visible') : setState('nothing is visible'); }, [onScreen]) debe agregar una dependencia en onScreen para que solo se actualice cuando onScreen haya cambiado y, por último, debe llamar a setState para el escenario cuando onScreen es falso al valor que desea.
Creo que el problema es cómo estás pasando elementRef al gancho.
useIntersect useEffect no se ejecutará cuando cambie elementRef.
import { useState, useEffect, useRef } from "react"; const useIntersect = () => { const ref = useRef(null); const [isOnScreen, setIsOnScreen] = useState(false); useEffect(() => { if (!ref) { const observer = new IntersectionObserver(([entry]) => setIsOnScreen(entry.isIntersecting) ); observer.observe(ref.current); return () => observer.disconnect(); } }, [ref]); return [isOnScreen, ref]; }; export default useIntersect; // -----------------------------Component------------------------------- const [state, setState] = useState("nothing is visible"); const [onScreen, elementRef] = useIntersect(); useEffect(() => { return onScreen ? setState("an item is visible") : null; }); return <Item ref={elementRef}></Item>;