这是使用React Hooks(带有)预加载组件中图像的半完整示例。您还可以将其制作为钩子。
在这些示例中,我们在此处使用和,但实际的预加载工作在我们拥有的函数内部进行。还请注意,导入图像会得到一个字符串。
直接添加到组件中
import React, { useEffect, useState } from 'react'
import Image1 from 'images/image1.png'
import Image2 from 'images/image2.jpg'
import Image3 from 'images/image3.svg'
const preloadSrcList: string[] = [
Image1,
Image2,
Image3,
]
function preloadImage (src: string) {
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = function() {
resolve(img)
}
img.onerror = img.onabort = function() {
reject(src)
}
img.src = src
})
}
export default function Component() {
const [assetsLoaded, setAssetsLoaded] = useState<boolean>(false)
useEffect(() => {
let isCancelled = false
async function effect() {
if (isCancelled) {
return
}
const imagesPromiseList: Promise<any>[] = []
for (const i of preloadSrcList) {
imagesPromiseList.push(preloadImage(i))
}
await Promise.all(imagesPromiseList)
if (isCancelled) {
return
}
setAssetsLoaded(true)
}
effect()
return () => {
isCancelled = true
}
}, [])
if (!assetsLoaded) {
return <p>Preloading Assets</p>
}
return <p>Assets Finished Preloading</p>
}
更好的方式是使用钩子:useImagePreloader()
import { useEffect, useState } from 'react'
function preloadImage (src: string) {
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = function() {
resolve(img)
}
img.onerror = img.onabort = function() {
reject(src)
}
img.src = src
})
}
export default function useImagePreloader(imageList: string[]) {
const [imagesPreloaded, setImagesPreloaded] = useState<boolean>(false)
useEffect(() => {
let isCancelled = false
async function effect() {
console.log('PRELOAD')
if (isCancelled) {
return
}
const imagesPromiseList: Promise<any>[] = []
for (const i of imageList) {
imagesPromiseList.push(preloadImage(i))
}
await Promise.all(imagesPromiseList)
if (isCancelled) {
return
}
setImagesPreloaded(true)
}
effect()
return () => {
isCancelled = true
}
}, [imageList])
return { imagesPreloaded }
}
在组件中使用 useImagePreloader()
import React, { useEffect, useState } from 'react'
import useImagePreloader from 'hooks/useImagePreloader'
import Image1 from 'images/image1.png'
import Image2 from 'images/image2.jpg'
import Image3 from 'images/image3.svg'
const preloadSrcList: string[] = [
Image1,
Image2,
Image3,
]
export default function Component() {
const { imagesPreloaded } = useImagePreloader(preloadSrcList)
if (!imagesPreloaded) {
return <p>Preloading Assets</p>
}
return <p>Assets Finished Preloading</p>
}