Estoy tratando de construir un componente de imagen en fallback con un accesorio de respaldo, si se proporciona, renderizará el componente de respaldo hasta que la imagen se haya descargado y renderizado correctamente.
La representación condicional es la siguiente:
if (loading) { return fallback; } else if (error) { return <span>ERROR</span>; } else if (src) { return ( <> <img alt="" ref={imageRef} decoding="async" src={props.src} /> </> ); } else return null; }Y la imagen se llama en el archivo App.js como
<Image src="https://source.unsplash.com/random/100x100" fallback={<h1>Loading...</h1>} /> Estoy usando useEffect gancho para llamar a la función que verifica aún más si la imagen se ha montado en la pantalla usando ref .
React.useLayoutEffect(() => { imageRef.current = true; start(); return () => { imageRef.current = false; }; }, []); async function start() { if (!src || !fallback) { const errorMessage = "`src` & `fallback` must be provided"; setError(errorMessage); return; } setLoading(true); tryLoadImage(); } async function loadImage() { const img = imageRef.current; if (!img) { return; } setLoading(false); } async function tryLoadImage() { try { await loadImage(); if (imageRef.current) { setLoading(false); } } catch (error) { console.log("error", error); } }El problema al que me enfrento:
return , el componente da un espacio en blanco y negro y luego representa la imagen, por lo tanto, no se representa "Cargando..." en la pantalla.Cosas de las que no estoy seguro:
Consulte el enlace de Codesandbox para ver la demostración/código en vivo: https://codesandbox.io/s/img-lazy-ke6zz
Cualquier ayuda en la dirección correcta sería muy útil.
Puedes usar useEffect mejor en este caso; tienes un estado de loading . Debería escuchar cuando este valor cambia en su useEffect .
useEffect(() => { setLoading(false); }, [loading]); El valor que pasa en la matriz en el enlace useEffect se está escuchando (puede haber más que valor aquí, ya que es una matriz). Entonces, cuando uno de esos valores cambia, ejecuta el código en useEffect. En este componente, loading solo debería cambiar una vez a falso. Entonces, cada vez que usa setLoading en su código, se ejecuta este useEffect.
Te recomiendo leer más sobre este gancho aquí: https://reactjs.org/docs/hooks-effect.html
Además, creo que es mejor en este caso, el estado de loading predeterminado es verdadero en lugar de falso. Entonces, cuando el componente se renderiza, se está cargando desde el principio. En la función de start , puede usar setLoading en falso cuando src o fallback no están configurados. Esta es también la razón por la que no se muestra su respaldo. Como la loading predeterminada es falsa y muestra el respaldo cuando esto se está loading es verdadero.
Una mejor práctica de usar React.useEffect y React.useState es importarlo en su archivo. Esto se puede hacer de la siguiente manera import React, { useRef, useEffect, useState } from "react"; . Entonces puedes usarlos así const [loading, setLoading] = useState(false); sin React prefijándolo.
Puede encontrar una versión editada de su CodeSandbox aquí https://codesandbox.io/s/img-lazy-forked-l8zuf?file=/src/Image.js . También cambié la declaración de devolución, lo que puede hacer si no desea mostrar errores.