图像加载前的占位符



我在屏幕上显示多个图像,我希望在加载每个图像时都有一个占位符和小动画。一旦它们被完全加载,我想显示该图像而不是";动画";。我现在所拥有的是,在API调用完成以获取项目后,我map遍历每个项目,并将其逐个呈现在屏幕上。

const [feedItems, setFeedItems] = useState([]);
// props from redux state
const { error, loading, items } = props;
useEffect(() => {
// dispatch action
props.fetchItems(0);
setFeedItems([...items]);
if (!loading) {
setLoaded(true);
}
}, [setFeedItems]);
return (
<div className="items">
{feedItems.map((item) => <Item key={item.id} item={item} loaded={loaded} />)}
</div>
)

我不想这样做。我想为该提要中的每个项目立即显示Item组件,但在加载图像后更改其css类。如下所示,如果图像未加载,则将css类设为item,加载后更改为item loaded-item

const Item = (props) => {
return (
<div className={`item ${props.loaded ? "loaded-item" : ""}`}>
...
</div>
)
}

我的问题是我不知道如何做到这一点。只有在API请求完成后,我的map函数才会呈现组件。我考虑了以下内容:

<Item key={item?[0]?.id} item={item?.[0]} loaded={loaded} />
<Item key={item?[1]?.id} item={item?.[1]} loaded={loaded} />
<Item key={item?[2]?.id} item={item?.[2]} loaded={loaded} />
.....

但对于这种方法,我将不得不添加[loaded]作为useEffect挂钩的依赖项,以在加载图像后不断更改图像,但这将产生大量连续的API请求(否则页面不会重新发送,图像也不会更改(。考虑到我将显示大约15个项目,并且必须这样做15次,并且当用户向下滚动以显示另外15个项目时还添加了分页,我相信代码会一团糟。有人能为如何在这里实现我想要的目标提供一些更好的解决方案吗?

当组件处于加载状态时,可以显示固定数量的占位符项。我在无限滚动加载中使用了这种方法。

请注意,占位符将没有item.id用作key,因此一旦项目完成加载,占位符将卸载,实际项目的新Item组件将装载。它不会是相同的组件实例。

const MyComponent = (props) => {
// props from redux state
const { error, loading, items } = props;
// update this, or import from some global constants file
const PER_PAGE = 12;
// the page to request - maybe it comes from redux
const [page, setPage] = useState(1);
// fetch next items when the page changes
useEffect(() => {
props.fetchItems(page);
}, [page]);

// call this on a button click or a scroll event
const loadNext = () => {
setPage(current => current + 1);
}
return (
<div className="items">
{items.map((item) => (
<Item key={item.id} item={item} loaded={true} />
))}
{loading && // show placeholders after loaded items when loading
Array.from({ length: PER_PAGE }).map((_, i) => (
<Item key={i} item={undefined} loaded={false} />
))}
</div>
);
};

你听说过React Suspense吗?

这可能是你的问题的答案,它应该在你加载真实图像时放置你的图像位置。然而,你的数据提取必须与之兼容,看看他们的第一个代码沙盒。

最新更新