No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Reto: sigamos extiendo el DOM

12/16
Recursos

Aportes 4

Preguntas 0

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Estuvo genial el reto, aprend铆 mucho de useEffect leyendo la documentaci贸n oficial de c贸mo remover las dependencias de useEffect buscando una soluci贸n al bug del segundo reto.
.
En resumen, aprend铆 que el linter siempre estar谩 pendiente de que agreguemos en el array de dependencias de useEffect todos los valores reactivos que usemos dentro del mismo, como props o estados. Como onLazyLoad es una funci贸n dentro de los props del componente LazyImage, React lo trata como un valor reactivo. Sin embargo, no queremos agregar esta funci贸n en las dependencias de useEffect, porque lo 煤nico que nos interesa de onLazyLoad es obtener sus datos, m谩s no ejecutar el callback de useEffect cada vez que onLazyLoad cambie.
.
La mejor soluci贸n en la documentaci贸n es utilizar el hook (en fase experimental a la fecha de escribir este comentario 15/03/23) useEffectEvent. Este hook le indica a useEffect que vamos a utilizar un valor reactivo dentro del mismo, pero no queremos que 鈥榬eaccione鈥 a sus cambios, sino que solamente lo use para lectura. Este hook al estar en fase experimental, prefer铆 no usarlo pero est谩 bastante interesante para cuando salga.
.
Al final, opt茅 por la opci贸n que React no recomienda, que es desactivar el linter. Como en todo, cada cosa a su momento, y en este caso desactivar el linter es la opci贸n que mejor se adapta a mi c贸digo porque solamente quiero leer lo que me arroja onLazyLoad, m谩s no reaccionar a sus cambios. Es de esos momentos cuando la soluci贸n menos recomendada resulta ser la m谩s 贸ptima para un caso espec铆fica, o por lo menos la m谩s sencilla seg煤n yo

interface LazyImageProps extends ImgHTMLAttributes<HTMLImageElement> {
  src: string
  alt: string,
	// especificamos que onLazyLoad es un valor opcional de tipo void que aceptar谩 un argumento de tipo HTMLImageElement
  onLazyLoad?: (node: HTMLImageElement) => void
}

export default function LazyImage({src, alt, onLazyLoad, ...imgOptionalAttrs}: LazyImageProps) {
  
  const node = useRef<HTMLImageElement>(null)
  
  const [currentSrc, setCurrentSrc] = useState(defaultImg)
  
  useEffect(() => {
    const intersectionObserver = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          setCurrentSrc(src)
					// ya que onLazyLoad es un valor opcional, validamos que sea verdadero y lo ejecutamos pasando el target de la entrada como argumento el cual contiene todos los datos del elemento img
          onLazyLoad && onLazyLoad(entry.target as HTMLImageElement)
					// le digo al intersectionObserver que deje de observar a img luego de entrar al viewport y ejecutar el c贸digo de arriba
          intersectionObserver.unobserve(entry.target)
        }
      })
    })
    
    node.current && intersectionObserver.observe(node.current)
    return () => { intersectionObserver.disconnect() }
	// DANGER ZONE: le digo al linter que ignore la l铆nea de abajo
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [src])

  return (
    <img ref={node} src={currentSrc} alt={alt} {...imgOptionalAttrs} />
  )
}

Yo lo solucione un poco diferente sin pasar el nodo y usando prevState

Mi solucion

interface Props extends ImgHTMLAttributes<HTMLImageElement> {
    src: string,
    onLazyLoad?: (node: HTMLImageElement) => void
}
useEffect(() => {
        const observer = new IntersectionObserver((entries) => {
            entries.forEach((entry) => {
                if(entry.isIntersecting) {
                    console.log("Hey")
                    setCurrentSrc(src)

                    if(node.current) {
                        onLazyLoad && onLazyLoad(node.current)
                        observer.disconnect()
                    }
                }
            })
        })

        if(node.current) {
            observer.observe(node.current)
        }

        return () => {
            observer.disconnect()
        }
}, [src, onLazyLoad])

Bueno no entend铆 el reto my bien, lo unico que pude enteder es que tipo de dato era la funcion onLazyLoad la cual logr茅, m谩s all谩 de eso no entend铆 mucho los retos. Aqu铆 dejo la primera parte del primer reto, OJO, NO EST脕 COMPLETO

C贸digo

type LazyImageProps = {
  src: string;
  onLazyLoad?: ()=> void 
};