gpt4 book ai didi

javascript - react : How do you lazyload image from API response?

转载 作者:行者123 更新时间:2023-12-05 02:05:35 26 4
gpt4 key购买 nike

我的网站太重了,因为它在从服务器(Google 的 Firebase Firestore)获取数据后下载了 200-400 张图像。

我想出了两个解决方案,我希望有人能回答其中一个:

  • 我想将每个 img 设置为具有加载状态,并使访问者能够在加载之前看到占位符图像。因为我不知道从服务器获取数据之前我得到了多少图像,所以我发现很难通过 useState 初始化图像加载状态。这可能吗?那么,如何?
  • 如何延迟加载图片?图像使用占位符进行初始化。当滚动条靠近图像时,图像开始下载并替换占位符。
function sample() {}{
const [items, setItems] = useState([])
const [imgLoading, setImgLoading] = useState(true) // imgLoading might have to be boolean[]
useEffect(() => {
axios.get(url).
.then(response => setItems(response.data))
}, [])
return (
items.map(item => <img src={item.imageUrl} onLoad={setImgLoading(false)} />)
)
}

最佳答案

我会创建一个 Image 组件来处理它自己的相关状态。然后在这个组件中,我会使用 IntersectionObserver用于判断图像容器在用户浏览器上是否可见的 API。

我会有 isLoadingisInview 状态,isLoading 将始终为 true 直到 isInview 更新为 true

虽然 isLoadingtrue,但我会使用 null 作为图像的 src 并将显示占位符。

当容器在用户浏览器上可见时,仅加载 src

function Image({ src }) {
const [isLoading, setIsLoading] = useState(true);
const [isInView, setIsInView] = useState(false);
const root = useRef(); // the container

useEffect(() => {
// sets `isInView` to true until root is visible on users browser

const observer = new IntersectionObserver(onIntersection, { threshold: 0 });
observer.observe(root.current);

function onIntersection(entries) {
const { isIntersecting } = entries[0];

if (isIntersecting) { // is in view
observer.disconnect();
}

setIsInView(isIntersecting);
}
}, []);

function onLoad() {
setIsLoading((prev) => !prev);
}

return (
<div
ref={root}
className={`imgWrapper` + (isLoading ? " imgWrapper--isLoading" : "")}
>
<div className="imgLoader" />
<img className="img" src={isInView ? src : null} alt="" onLoad={onLoad} />
</div>
);
}

我还会有 CSS 样式来切换占位符和图像的 display 属性。

.App {
--image-height: 150px;
--image-width: var(--image-height);
}

.imgWrapper {
margin-bottom: 10px;
}

.img {
height: var(--image-height);
width: var(--image-width);
}

.imgLoader {
height: 150px;
width: 150px;
background-color: red;
}

/* container is loading, hide the img */
.imgWrapper--isLoading .img {
display: none;
}

/* container not loading, display img */
.imgWrapper:not(.imgWrapper--isLoading) .img {
display: block;
}

/* container not loading, hide placeholder */
.imgWrapper:not(.imgWrapper--isLoading) .imgLoader {
display: none;
}

现在我的父组件将执行对所有图像 url 的请求。它还会有自己的 isLoading 状态,当设置为 true 时,它会显示自己的占位符。当图像 url 的请求得到解决时,我将映射到每个 url 以呈现我的 Image 组件。

export default function App() {
const [imageUrls, setImageUrls] = useState([]);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
fetchImages().then((response) => {
setImageUrls(response);
setIsLoading((prev) => !prev);
});
}, []);

const images = imageUrls.map((url, index) => <Image key={index} src={url} />);

return <div className="App">{isLoading ? "Please wait..." : images}</div>;
}

Edit flamboyant-kare-zz6qq

关于javascript - react : How do you lazyload image from API response?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63405009/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com