Я недавно создал компонент React (называемый ItemIndexItem), который отображает изображения в моем приложении. Например, у меня есть компонент поиска, который будет показывать индекс отфильтрованных элементов. Каждый отображаемый элемент является компонентом ItemIndexItem. Нажатие ItemIndexItem отправляет вас на страницу ItemShow, где используется тот же ItemIndexItem.
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
до нуля:
return () => img = null;
Это ничего не делает, однако. Поскольку я не создаю подписку, удалить ее не буду. Поэтому я думаю, что проблема заключается в асинхронной природе .onload
.