【发布时间】:2020-06-23 07:19:12
【问题描述】:
假设我想创建一个组件来渲染图像。如果图像资源有效,我应该通过 css background-image 将其渲染为 div。否则,我应该将其呈现为带有 alt 标记的标准 <img>。
所以我们得到这样的结果:
const ImageComponent = ({src}) => {
const [loaded, setLoaded] = useState(false);
const [renderFallback, setRenderFallback] = useState();
useEffect(() => {
const image = new Image();
image.onsuccess = () => {
setLoaded(true);
setRenderFallback(false);
}
image.onerror = () => {
setLoaded(true);
setRenderFallback(true);
}
image.src = src;
return () => {
// clean up listeners
image.onsuccess = undefined;
image.onerror = undefined;
}
}, [src]);
if (!loaded) { return null; }
return renderFallback ?
<div style={{backgroundImage: `url(${src})`}}/> :
<img src={src} alt="my alt"/>;
}
在这里,我们首先通过纯 javascript(在 useEffect 中)开始获取图像。如果有效,则资源被缓存(由浏览器),随后的<div> 的呈现是瞬时的。
但是,如果资源无效,则没有适当的缓存机制(有关详细信息,请参阅this question)。因此,当我们在组件末尾渲染新的 <img> 元素时,它会启动一个全新的请求来获取该图像(尽管推断它已经损坏)。
因此,为了避免这种重复获取,一个可能的解决方案是渲染已经初始化的 image 元素,而不是一个新的 react 元素来表示该图像。
这可能吗?
来自 cmets 的反馈
- 无效图像是指返回状态为 404 或指向的资源实际上不是图像(例如
https://goodreads.com) - 我想在浏览器损坏的情况下显示浏览器的默认“损坏图像”。这不能通过
background-imagecss 完成,所以我需要依赖一个标准的<img>元素。由于我已经确定图像已损坏(在 useEffect 中),因此我想在 React 中渲染损坏的<img>时避免重新获取。
希望能澄清事情!
【问题讨论】:
-
您好,您能解释一下您所说的无效图像吗?这是您要上传的图片吗?
-
用户
React.memo()以避免不必要的重新渲染组件。更多详情请参考链接scotch.io/tutorials/… -
不确定您在这里尝试做什么,404 仍然需要时间。如果你说这个 404 总是无效的,你想以这种方式缓存它。然后你可以做的是使用 localeStorage 将此网址标记为无效..
-
@t3__rry 这与我链接的另一个问题有关。无效图像是指向非图像资源(例如
https://goodreads.com)的图像,或者返回状态为 404 的图像 -
我相信我理解你之后的内容,你的 React 代码看起来不远了,你没有传递 props 而是 src,所以这没有意义,但除此之外它看起来有点像修改后,您可以在使用 Session/LocaleStorage 后执行此操作,甚至可以选择自定义到期日期等。如果您可以敲出一个 sn-p,我可以更改它。
标签: javascript html css reactjs