我正在尝试通过在组件安装时执行异步操作来更新反应中的状态。我在images
道具中有一个图像ID的列表,从头开始,在安装时,该组件应该遍历每个ID,并在Firebase存储中获取图像的实际URL。但是,包含url的数组一次只能在其中获得一个url,尽管已通过images属性将许多id传递给了它。我在做什么错了?
import React, { useEffect, useState } from 'react';
import { Panel, Carousel, Divider } from 'rsuite';
import { storage } from '../../misc/firebase';
const ListingItem = ({ title, images, owner, props }) => {
const [imageUrls, setImageUrls] = useState([]);
useEffect(() => {
for (const img in images) {
storage
.ref(`listings/${owner}/images`)
.child(images[img])
.getDownloadURL()
.then(url => setImageUrls([...imageUrls, url])); // this should append the url to imageUrls
}
}, []);
return (
<Panel
{...props}
shaded
bordered
bodyFill
style={{ display: 'inline-block', height: '100' }}
>
<Carousel>
{ /* This only ever outputs a single image */ }
{imageUrls.length !== 0 &&
imageUrls.map((img, idx) => <img src={img} key={idx} />)}
</Carousel>
<Panel header={title}>
<small>foo</small>
</Panel>
</Panel>
);
};
export default ListingItem;
答案 0 :(得分:2)
useEffect
回调在装入时仅运行一次。挂载时,imageUrls
状态变量被初始化为空数组。结果,在useEffect
回调中,这是
.then(url => setImageUrls([...imageUrls, url]));
将始终等同于:
.then(url => setImageUrls([, url]));
因为初始数组为空。
请改用回调形式,以便您根据当前状态设置新的状态 ,而不是根据旧的(现在可能已过时)闭包中的变量进行设置:
.then(url => setImageUrls(currentImageUrls => [...currentImageUrls, url]));