我最近构建了一个React组件(称为ItemIndexItem),该组件在我的应用程序上显示图像。例如,我有一个搜索组件,它将显示已过滤项目的索引。显示的每个项目都是一个ItemIndexItem组件。单击ItemIndexItem会将您转到使用相同ItemIndexItem的ItemShow页面。
Search.jsx
render() {
return (
<ul>
<li key={item.id}>
<div>
<Link to={`/items/${item.id}`}>
<ItemIndexItem src={item.photos[0].photoUrl} />
<p>${item.price}</p>
</Link>
</div>
</li>
...more li's
</ul>
)
}
ItemIndexItem.jsx
import React,{ useState,useEffect } from "react";
export default function ItemIndexItem(props) {
const [imageIsReady,setImageIsReady] = useState(false);
useEffect(() => {
let img = new Image();
img.src = props.src;
img.onload = () => {
setImageIsReady(true);
};
});
if (!imageIsReady) return null;
return (
<div>
<img src={props.src} />
</div>
);
}
除了控制台中引发的内存泄漏错误之外,该组件的工作状况完全符合要求:
无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消使用useEffect清理功能中的所有订阅和异步任务。
在ItemIndexItem中(由ItemShow创建)
在div中(由ItemShow创建)
作为参考,这是在ItemShow中渲染我的ItemIndexItem的代码:
ItemShow.jsx
return (
...
<div>
<ul>
{this.props.item.photos.map(photo => {
return (
<li key={photo.photoUrl}>
<div>
<ItemIndexItem type='show' src={photo.photoUrl} />
</div>
</li>
);
})}
</ul>
</div>
...
我尝试利用useEffect返回函数将img
设置为null:
return () => img = null;
但是,这什么都不做。由于我没有创建订阅,因此没有要删除的订阅。因此,我认为问题在于.onload
的异步性质。