¿Cómo puedo esperar hasta que se carguen todas las imágenes en React.JS?
El problema es que hago algunos cálculos (procesamiento de imágenes) usando esas imágenes y los resultados son diferentes entre varias actualizaciones del navegador porque en ciertos momentos los cálculos comienzan antes de que las imágenes estén cargadas al 100%. ¿Hay alguna manera de esperar hasta que se cargue el 100% de todas las imágenes?
He intentado algo como esto:
const [imagesLoaded, setImagesLoaded] = useState(false);
{images.map((image, index) => { return <ShowImage source={image} index={index+1} key={index} onLoad={() => setImagesLoaded(index)} /> })}
const ShowImage: React.FC<{source:string, index: number, onLoad: () => void}> = ({source, index, onLoad}) => { return ( <img src={source} width="640" height="480" id={'image' + index} alt={'image' + index} onLoad={onLoad}/> ) }
Y el 'comprobador':
useEffect(() => { if(imagesLoaded === 5) { ... do something } }, [imagesLoaded]);
Pero el problema es que esto funciona solo para el procesamiento de la primera página, si actualizo no funciona, pero actualizo una vez más funciona de nuevo y, a veces, necesita más actualizaciones, ¿cuál es el problema?
Es posible que sus imágenes no se carguen en el orden previsto. Si su cuarta imagen se carga después de la quinta, entonces el valor de imagesLoaded
será 4
al final. Para evitar eso, incrementaría el valor de uno en uno, de modo que cuando se carguen las cinco imágenes, el valor será 5.
onLoad={() => setImagesLoaded(v => v + 1)}
Puede refactorizar su componente ShowImage
para establecer solo imagesLoaded
cuando se carga la URL de origen de la última imagen.
function ShowImages({ urls, setImagesLoaded }) { const onLoad = (index) => { if (index === urls.length - 1) { setImagesLoaded(true) } }; return ( <> {urls.map((url, index) => ( <img src={url} onLoad={() => onLoad(index)} key={url} /> ))} </> ); } export default ShowImages;
Y usa el componente algo como esto
const [imagesLoaded, setImagesLoaded] = useState(false); ... useEffect(() => { if(imagesLoaded) { ... do something } }, [imagesLoaded]); ... <ShowImages urls={images} setImagesLoaded={setImagesLoaded}/>