reactjs - 反应 useEffect 没有正确更新状态
问题描述
我正在尝试通过在组件安装时执行异步操作来更新状态。我在images
道具中有一个图像ID列表,开始时组件应该遍历每个ID并获取Firebase存储中图像的实际URL。然而,包含 url 的数组一次只能获得一个 url,尽管有许多 id 通过 images 属性传递给它。我究竟做错了什么?
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;
解决方案
回调仅在useEffect
挂载时运行一次。在挂载时,imageUrls
状态变量被初始化为空数组。结果,在useEffect
回调内部,这是:
.then(url => setImageUrls([...imageUrls, url]));
将始终等同于:
.then(url => setImageUrls([, url]));
因为初始数组是空的。
请改用回调形式,以便根据当前状态设置新状态,而不是根据旧(现在可能已过时)闭包中的变量:
.then(url => setImageUrls(currentImageUrls => [...currentImageUrls, url]));
推荐阅读
- r - R中的函数acf计算自相关
- cube.js - Cube.js:错误:使用 MongoDB BI 连接器使用明文身份验证时需要 ssl
- python - 验证损失和验证准确度曲线随预训练模型波动
- excel - 如何以编程方式将 vb 宏插入另一个工作簿
- c - 使用 fgets() 和 strtok() 从 CSV 读取
- php - Symfony 3.4 测试失败并出现 PHPUnit\Framework\Exception:但没有消息
- python - 如何通过加法找到csv文件的最大值
- windows - Makefile:23:目标“allmodes”的配方失败
- image - 如何在不分割对象的情况下对图像进行二值化
- javascript - Sinon 存根未替换测试中的功能