Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorporación de useNearScreen a los Gifs #6

Open
alvaaz opened this issue May 12, 2020 · 1 comment
Open

Incorporación de useNearScreen a los Gifs #6

alvaaz opened this issue May 12, 2020 · 1 comment

Comments

@alvaaz
Copy link

alvaaz commented May 12, 2020

¿Cómo quedaría el hook useNearScreen para la utilización en los Gifs?
En la implementación de vistas quedaría así:

ListOfGifs.js

 {
      gifs.map(({id, title, url}) =>
        <Gif
          id={id}
          key={id}
          title={title}
          url={url}
        />
      )
    }

Gif.js

export default function Gif ({ title, id, url }) {
  const { isNearScreen, fromRef } = useNearScreen();

  return (
    <div className="Gif" ref={fromRef}>
    {isNearScreen &&
      <Link to={`/gif/${id}`} className='Gif-link'>
        <h4>{title}</h4>
        <img loading='lazy' alt={title} src={url} />
      </Link>
     }
    </div>

  )
}

Pero esto repetiría el useScreenNear por cada Gif, ¿como poder utilizar el argumento de entries para observar a todos los gif sin tener que repetir todo el hook por cada Gif?.

@alvaaz
Copy link
Author

alvaaz commented Jun 9, 2020

Tengo una propuesta para manejar varios GIF con un único hook. La idea es utilizar la API Intersection Observer para que la carga sea cuando el viewport este cerca del elemento, y cuando mientras el elemento no se haya cargado completamente se muestre una imagen por default. Para ello, todos los componentes Gif deberían tener un identificador para poder llamarlos mediante querySelectorAll y utilizar src para guardar la imagen mientras carga y data-src para guardar en enlace a la imagen que debiese mostrar finalmente.

export const useLazyLoading = (imgSelector, items) => {
  const imgObserver = useCallback(node => {
    const intObs = new IntersectionObserver(entries => {
      entries.forEach(en => {
        if (en.isIntersecting) {
          const currentImg = en.target;
          const newImgSrc = currentImg.dataset.src;
          if (!newImgSrc) {
            console.error("Image source is invalid");
          } else {
            currentImg.src = newImgSrc;
          }
          intObs.unobserve(node);
        }
      });
    });
    intObs.observe(node);
  }, []);

  const imagesRef = useRef(null);

  useEffect(() => {
    imagesRef.current = document.querySelectorAll(imgSelector);
    if (imagesRef.current) {
      imagesRef.current.forEach(img => imgObserver(img));
    }
  }, [imgObserver, imagesRef, imgSelector, items]);
};

Me gustaría que en vez de que se muestre una imagen por defecto mientras cargue, utilizar un ContentLoader, que una vez se haya cargado la imagen desaparezca y muestre la imagen cargada y evitar este tipo de situaciones:

image

Que la imagen aún se este cargando y que el usuario vea esto:

image

¿Alguien tiene propuesta para esto?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant