React.js에서 이미지를 프리로드하는 방법
React.js에서 이미지를 프리로드하는 방법메뉴와 같이 동작하는 드롭다운 선택 컴포넌트가 있습니다만, 처음에 열었을 때 보이지 않을 수 있기 때문에 아이템의 이미지 아이콘을 미리 로드해야 합니다.
시도했습니다.
https://github.com/sambernard/react-preload
https://github.com/wizardzloy/react-img-preload
첫 번째는 이해하기 쉽고 사용하기 쉬운 API를 갖추고 있지만 이미지가 로드되어도 로드되지 않았다는 경고를 표시하는 Spaming Console입니다.두 번째는 이상한 API를 가지고 있는데 예를 들어봤는데 아무것도 프리로드 되지 않았습니다.
그래서 아마 저 스스로 무언가를 구현해야 할 것 같습니다만, 어디서부터 시작해야 할지 모르겠습니다.또는 웹 팩을 로드하는 방법도 있습니다.
pictures: string[];
URL 배열 컴' 、 컴 - 、 URL 。 정의해야 .componentDidMount()
컴포넌트 내의 메서드를 작성한 후 새로 만들기Image
"CHANGE: "CHANGE: "CHANGE:
componentDidMount() {
this.props.pictures.forEach((picture) => {
const img = new Image();
img.src = picture.fileName;
});
}
브라우저가 모든 이미지를 강제로 로드합니다.
은 리액트입니다(「」를 사용).TypeScript
컴포넌트 내부에 이미지를 프리로드하는 방법.후크로도 만들 수 있어요.
에서는 '이렇게'를 사용하고 .useEffect
★★★★★★★★★★★★★★★★★」useState
여기입니다만, 실제 프리 로딩 작업은,preloadImage()
기능을 가지고 있습니다.수입하다
구성 요소 내부에 직접 추가
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>
}
후크로서 최적: use Image Preloader()
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>
}
이 되지 경우 를 .window
object :
componentDidMount() {
const imagesPreload = [image1, image2, image3];
imagesPreload.forEach((image) => {
const newImage = new Image();
newImage.src = image;
window[image] = newImage;
});
}
window
(오브젝트)
리액션 훅 방식
useEffect(() => {
//preloading image
faceArray.forEach((face) => {
const img = new Image();
img.src = face;
});
}, []);
이 방법은 다음과 같습니다.
import im1 from 'img/im1.png'
import im2 from 'img/im2.png'
import im3 from 'img/im3.png'
componentDidMount() {
imageList = [im1, im2, im3]
imageList.forEach((image) => {
new Image().src = image
});
}
이 기능을 모든 기능 컴포넌트에서 사용할 수 있는 커스텀훅에 넣는 방법을 다음에 나타냅니다.
일부 답변이 누락된 중요한 부분은 미리 로드된 이미지에 대한 참조를 창 개체와 같은 곳에 저장하는 것입니다.이렇게 하지 않으면 이미 이미지가 미리 로드되어 있음에도 불구하고 브라우저가 실제로 필요한 이미지를 다시 요구할 수 있습니다.
훅을 할 때 가 훅에 됩니다.window
라고 하는usePreloadImagesData
기izedizedizedizedizedizedizedizedizedized로 초기화 됩니다.{}
.
컴포넌트에 키가 됩니다.window.usePreloadImagesData
으로 생성됩니다. 키의 이름은 임의로 생성됩니다.되어 있습니다.[]
.
후크는 이미지 소스 문자열 배열을 사용합니다.소스에 , 「」를 해 주세요.new Image()
되어 있습니다.window.usePreloadImagesData[randomStr]
manager.manager로 하다
배열이 되면 " " "는 " " " 입니다.window.usePreloadImagesData[randomStr]
메모리 누수를 방지하기 위해 이 삭제됩니다.
이 예는 Typescript에 기재되어 있습니다.
import { useEffect } from 'react';
declare global {
interface Window {
usePreloadImagesData?: Record<string, unknown[]>;
}
}
export const usePreloadImages = (imageSrcs: string[]): void => {
useEffect(() => {
const randomStr = Math.random().toString(32).slice(2) + Date.now();
window.usePreloadImagesData = window.usePreloadImagesData ?? {};
window.usePreloadImagesData[randomStr] = [];
for (const src of imageSrcs) {
// preload the image
const img = new Image();
img.src = src;
// keep a reference to the image
window.usePreloadImagesData[randomStr].push(img);
}
return () => {
delete window.usePreloadImagesData?.[randomStr];
};
}, [ imageSrcs ]);
};
이 후크를 사용할 때는 후크에 전달되는 이미지 소스 문자열 배열이 일정하게 유지되는지 확인하십시오. 하거나 ,, or, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, like, like, like, like, like 을 사용합니다.React.useMemo
.
예.
import React from 'react';
import { usePreloadImages } from '../hooks/usePreloadImages';
import img1 from './image-1.jpg';
import img2 from './image-2.jpg';
const preload = [ img1, img2 ]; // create constant array here, outside the component
export const MyComponent: React.FC = () => {
usePreloadImages(preload); // correct
// usePreloadImages([ img1, img2 ]); // incorrect
return (
// ...
);
};
몇 개의 작은 "아이콘" (글꼴을 사용하지 않는 이유)만 전달하고 서버가 gzipped 파일을 제공하는 경우 base64를 사용할 수 있습니다.
않으면 추가할 .display: none
이전 HTML에 또 다른 하고 를 기다리는 입니다.DOM.onload
컴포넌트를 표시하기 전에 (이 접근법은 말씀하신 라이브러리에서 사용됩니다)
웹 팩이나 리액션은 여기서 특별한 일을 해줄 수 없습니다.이것은 클라이언트측의 것으로, 독자적인 프리로드 API(또는 JS/TS, React, Angular 등의 기존 API 사용)를 실장하기 위한 툴에 지나지 않습니다.
음, 친구여, 링크 릴 프리로드 / 프리페치 및 webpack lazy loading chunks 옵션이 몇 가지 있습니다.
상세 정보:
https://github.com/GoogleChromeLabs/preload-webpack-plugin
단일 구성 요소 내에서만 이미지를 사전 로드해야 하는 경우:
const preloadedSpinner = useRef();
useEffect(() => {
preloadedSpinner.current = new Image();
preloadedSpinner.current.src = "my/image/source";
}, []);
을 src로 할 수 .display: none
자신의 상태에 따라 이미지가 나타나도록 스타일링을 삭제하기만 하면 됩니다.이렇게 하면 이미지가 미리 로드되지만 필요할 때까지 표시되지 않습니다.하다
<SliderItem
style={slideIndex === 1 ? null : { display: 'none' }}
src={imgSrc}
alt={'Kitchen furniture'}
text={'Caption Text'}
textStyle={classes.text}
MySlides={classes.MySlides}
/>
<SliderItem
style={slideIndex === 2 ? null : { display: 'none' }}
src={'/bedroom.jpg'}
alt={'Bedroom furniture'}
text={'Caption Text'}
textStyle={classes.text}
MySlides={classes.MySlides}
/>
<SliderItem
style={slideIndex === 3 ? null : { display: 'none' }}
src={'/living-room.jpg'}
alt={'Living-room furniture'}
text={'Caption Text'}
textStyle={classes.text}
MySlides={classes.MySlides}
/>
다음의 커스텀 훅을 사용할 수 있습니다.
import { useEffect, useState } from 'react';
const preloadImage = (src: string): Promise<HTMLImageElement> =>
new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = img.onabort = () => reject();
img.src = src;
});
const useImagePreloader = (imageList: string[]) => {
const [imagesPreloaded, setImagesPreloaded] = useState(false);
useEffect(() => {
let isCancelled = false;
const preloadImages = async () => {
const imagesPromiseList: Promise<HTMLImageElement>[] = imageList.map((img) =>
preloadImage(img),
);
try {
await Promise.all(imagesPromiseList);
} catch (error: unknown) {
console.error(error);
}
if (isCancelled) {
return;
}
setImagesPreloaded(true);
};
preloadImages();
return () => {
isCancelled = true;
};
}, [imageList]);
return { imagesPreloaded };
};
export default useImagePreloader;
리액트 서스펜스를 사용하여 이미지를 프리로드 할 수 있습니다!
- 내 경우 내 이미지에 대한 초기 src 속성으로 시작하고 브라우저에 이미지가 로드된 후 이미지 변경을 지연시키고자 합니다.
import { useEffect, useState } from 'react';
export const useImageLoader = (initialSrc: string, currentSrc: string) => {
const [imageSrc, _setImageSrc] = useState(initialSrc);
useEffect(() => {
const img = new Image();
img.onload = () => {
_setImageSrc(currentSrc);
};
img.src = currentSrc;
}, [currentSrc]);
return [imageSrc];
};
리액트용
import imageToScroll ...
const [imageIsLoaded, setImageIsLoaded] = useState(false);
useEffect(() => {
let img = new Image();
img.src = image.imageToScroll;
}, [imageIsLoaded])
<img src={image.imageToScroll}
onLoad={() => setImageIsLoaded(true)}
/>
예를 들어,images
각 이미지에 대한 데이터를 포함하는 배열로, 한 줄에서 수행할 수 있습니다.
componentDidMount() {
this.props.images.forEach(image => (new Image().src = image.src));
}
이것은 매우 늦은 답변입니다.React Fluent UI 컴포넌트의 드롭다운 이미지를 렌더링하는 것과 같은 문제가 있었습니다.해결방법은 파일 확장자를 .png에서 .jpg로 변경하고 확장자도 계속 업데이트하는 것이었습니다.바로 그거야!
언급URL : https://stackoverflow.com/questions/42615556/how-to-preload-images-in-react-js
'it-source' 카테고리의 다른 글
oracle - 커밋해야 할 스테이트먼트는 무엇입니까? (0) | 2023.03.07 |
---|---|
스프링 부트 Java Config Set 세션타임아웃 (0) | 2023.03.07 |
Spring Boot application.yml 파일에서 @Scheduled fixedRate 값을 삽입합니다. (0) | 2023.03.07 |
Wordpress - 현재 페이지가 로그인 페이지인지 여부를 감지하는 방법 (0) | 2023.03.07 |
지시문 템플릿 강제 다시 로드 (0) | 2023.03.07 |