如何在 React JS 组件中预加载图像?
How to preload image in a React JS component?
当 signInError
发生时,我正在渲染一个子组件。 signInError
存储在父组件中,如果它不为 null,它会根据以下代码呈现 <SignInError/>
组件:
ParentComponent.js
// Some code...
render() {
return(
<div>
<SignInForm
doSignIn={this.doSignIn}
resetSignInError={this.resetSignInError}
signInError={this.state.signInError}
/>
{this.state.signInError && <SignInError/>}
</div>
);
}
到目前为止一切顺利,这是子组件 SignInError.js
import React from 'react';
import RoundImage from '../../../UI/Common/RoundImage';
import Newman from '../../../../assets/newman-min.png';
class SignInError extends React.Component {
constructor(props){
super(props);
}
componentDidMount(){
const img = new Image();
img.src = Newman;
}
render(){
return(
<div>
<div>
<RoundImage src={img.src}/> // <--- img is undefined here!!!
</div>
<div>
Hello... Newman!
</div>
</div>
);
}
}
export default SignInError;
RoundImage.js
import React from 'react';
const RoundImage = (props) => {
return (
<div>
<img src={props.src}/>
</div>
);
}
export default RoundImage;
How to preload images in React.js?
Stack Over 流程上的这个问题的答案(link 以上)告诉我在 componentDidMount()
方法中创建 img
对象以强制浏览器加载它。正如您从上面的代码中看到的那样,我也这样做了。但是现在,当我尝试将它作为道具传递给我的 render
方法中的孙子组件时,我无法访问 img
,因为它是在另一个方法内部定义的。
最好的解决方法是什么?我只需要加载图像并与错误消息一起显示。否则,如果您的浏览器尚未缓存图像,则错误消息将显示在图像之前。感谢您的帮助。
有点不同的方法,但如果您事先有图像源,您可以将图像源添加到主 html 文件作为带有预加载选项的 link ref。浏览器会预加载图片(优先级相对较低),当您的应用加载图片时,它应该缓存在浏览器内存中。
<head>
..
..
<link rel="preload" href="<your_image_source_here>" as="image">
...
</head>
在这种方法中,我们将预加载过程与代码分开。当您提前(而不是动态)拥有图像源并且不需要缓存大量图像时(在中添加大量 links 会有点乱) html 头,尽管可能)
您可以在此处了解有关 link 预加载的更多信息:Preloading content with rel="preload"
图片下载发生在浏览器中。渲染到 DOM 也发生在浏览器中。
通过预加载,您的意思是您希望组件仅在图像准备就绪时呈现吗?
如果是这样,您可以这样做:
componentDidMount() {
const img = new Image();
img.onload = () => {
// when it finishes loading, update the component state
this.setState({ imageIsReady: true });
}
img.src = Newman; // by setting an src, you trigger browser download
}
render() {
const { imageIsReady } = this.state;
if (!imageIsReady) {
return <div>Loading image...</div>; // or just return null if you want nothing to be rendered.
} else {
return <img src={Newman} /> // along with your error message here
}
}
在我的例子中,我从我的图像的初始 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];
};
当 signInError
发生时,我正在渲染一个子组件。 signInError
存储在父组件中,如果它不为 null,它会根据以下代码呈现 <SignInError/>
组件:
ParentComponent.js
// Some code...
render() {
return(
<div>
<SignInForm
doSignIn={this.doSignIn}
resetSignInError={this.resetSignInError}
signInError={this.state.signInError}
/>
{this.state.signInError && <SignInError/>}
</div>
);
}
到目前为止一切顺利,这是子组件 SignInError.js
import React from 'react';
import RoundImage from '../../../UI/Common/RoundImage';
import Newman from '../../../../assets/newman-min.png';
class SignInError extends React.Component {
constructor(props){
super(props);
}
componentDidMount(){
const img = new Image();
img.src = Newman;
}
render(){
return(
<div>
<div>
<RoundImage src={img.src}/> // <--- img is undefined here!!!
</div>
<div>
Hello... Newman!
</div>
</div>
);
}
}
export default SignInError;
RoundImage.js
import React from 'react';
const RoundImage = (props) => {
return (
<div>
<img src={props.src}/>
</div>
);
}
export default RoundImage;
How to preload images in React.js?
Stack Over 流程上的这个问题的答案(link 以上)告诉我在 componentDidMount()
方法中创建 img
对象以强制浏览器加载它。正如您从上面的代码中看到的那样,我也这样做了。但是现在,当我尝试将它作为道具传递给我的 render
方法中的孙子组件时,我无法访问 img
,因为它是在另一个方法内部定义的。
最好的解决方法是什么?我只需要加载图像并与错误消息一起显示。否则,如果您的浏览器尚未缓存图像,则错误消息将显示在图像之前。感谢您的帮助。
有点不同的方法,但如果您事先有图像源,您可以将图像源添加到主 html 文件作为带有预加载选项的 link ref。浏览器会预加载图片(优先级相对较低),当您的应用加载图片时,它应该缓存在浏览器内存中。
<head>
..
..
<link rel="preload" href="<your_image_source_here>" as="image">
...
</head>
在这种方法中,我们将预加载过程与代码分开。当您提前(而不是动态)拥有图像源并且不需要缓存大量图像时(在中添加大量 links 会有点乱) html 头,尽管可能)
您可以在此处了解有关 link 预加载的更多信息:Preloading content with rel="preload"
图片下载发生在浏览器中。渲染到 DOM 也发生在浏览器中。
通过预加载,您的意思是您希望组件仅在图像准备就绪时呈现吗?
如果是这样,您可以这样做:
componentDidMount() {
const img = new Image();
img.onload = () => {
// when it finishes loading, update the component state
this.setState({ imageIsReady: true });
}
img.src = Newman; // by setting an src, you trigger browser download
}
render() {
const { imageIsReady } = this.state;
if (!imageIsReady) {
return <div>Loading image...</div>; // or just return null if you want nothing to be rendered.
} else {
return <img src={Newman} /> // along with your error message here
}
}
在我的例子中,我从我的图像的初始 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];
};