即使 .map 循环通过数组的所有索引,也无法在我的 React 应用程序中的 array.map 中显示我的 JSX 中的图像
Posted
技术标签:
【中文标题】即使 .map 循环通过数组的所有索引,也无法在我的 React 应用程序中的 array.map 中显示我的 JSX 中的图像【英文标题】:Cannot display images in my JSX from my array.map in my react app even though .map loops though all index of array 【发布时间】:2021-03-18 13:31:54 【问题描述】:问题:为什么 react 不在 JSX 中显示我的图像s?我怎样才能让它显示图像s?
编辑:我怀疑的问题不在于我获取数据的方式,而是我尝试显示/渲染图像的方式,我已在下面的主要问题下标记。
我有一个功能组件,它有一个 useEffect 从 firebase 获取 JSON 对象。
useEffect(()=>
axios
.get("http://localhost:9998/api/v1/fault/" + lastURLSegment)
.then((response) =>
setDisplay(response.data)
)
,[])
然后我提取 imageURL 值并查询 firebase 以返回一个可在网络上查看的 url 例如https://firebasestorage.googleapis.com/v0/b/$results.bucket/o/$encodeURIComponent(item)?alt=media
一旦我能够获取图像的 URL,我将 setState 放入一个名为 objUrl 的数组中
编辑:有objOfUrl和objUrl,objOfUrl是一个var [],objOfUrl是一个状态
useEffect(()=>
// displayspecificCases.imgURL = "fault/asd.jpg"
let foo = displayspecificCases.imageurl // "fault/asdfsdf.jpg,fault/1234.jpg..."
if (foo !== undefined)
console.log(foo) //console logs 2 images in string saperated by comma
let bar = foo.split(','); // bar is now an array ['fault/asdfsdf.jpg','fault/1234.jpg']
let i = 0;
bar.map((item)=>
console.log(item)
if(item !== "")
firebase.storage().ref()
.child(item)
.getMetadata()
.then((results) =>
objOfUrl[i] = `https://firebasestorage.googleapis.com/v0/b/$results.bucket/o/$encodeURIComponent(item)?alt=media`
i++ // i ++ for objOfUrl
console.log("i is :" + i)
trysetObjUrl(objOfUrl)catch(e)console.log("err is in view useEffect try catch e : " + e)
)
.catch((err) =>
console.log(err);
);
console.log(objOfUrl); //console logs [0: "url.....", 1: "url....."]
)
,[displayspecificCases])
主要问题在这里! 所以我想在 JSX 中显示图像。所以我将数组设置为一个状态并尝试使用 .map 来返回数组中的每个项目,这样我就可以使用 img 标签来显示它们
// inside the JSX
objUrl.map((item, i) => console.log(i); return <div class="column"> <img key=i src=item /> </div>)
但现在的问题是只显示 1 张图像而不是整个数组。此外,无论何时渲染,它似乎都会随机显示数组内的一个图像。如何显示数组内的所有图像?非常感谢!
旁注:我知道我的代码很乱,我还在学习中,请就如何改进某些部分提供建议和技巧!
【问题讨论】:
什么是objOfUrl
?它在哪里声明/定义?我的直觉是你正在改变你的状态对象,并且没有根据objOfUrl[i] = '.......'
和setObjUrl(objOfUrl)
行正确更新状态。
为什么不试试 Display.map 而不是 objUrl.map?不是图片所在的位置吗?
@DrewReese objOfUrl 是一个用其他常量声明的数组 var。我将编辑我的问题以包含它。关于状态对象的突变,当我做一个控制台日志时,它显示了两个图像 URL,希望能解决问题。我现在的问题是 jsx 没有渲染 objUrl 中的任何内容
请记住,在 Firebase 存储上,您需要获取“downloadUrl”firebase.google.com/docs/storage/web/download-files 以便显示它
@CyrusZei 我可以显示 1 张图片,但数组中有 2 个 url,所以应该显示 2,但只有 1 个
【参考方案1】:
如果我正确理解了您的代码,它正在执行的操作:
displayspecificCases
更新触发的效果回调
将displayspecificCases.imageurl
拆分为网址数组
为图像所在的存储桶调用 firebase 后端以获得真实图像 URL
问题
你正在改变你的 objOfUrl
状态对象。
objOfUrl[i] = `https://firebasestorage.googleapis.com/v0/b/$results.bucket/o/$encodeURIComponent(item)?alt=media`
您将标准状态更新排入一个循环中。这会使用上一个渲染周期中的状态值将所有状态更新排入队列(记住状态是const
)。这也是一个问题,因为objOfUrl
IS 是状态引用。它应该是一个新的数组引用。
setObjUrl(objOfUrl)
我想这不是您的问题的原因,但使用 array.prototype.map
发出数组副作用是不正确的。
解决方案
使用功能状态更新来
-
在循环中正确地将状态更新排入队列
正确返回新的状态数组引用
代码
useEffect(() =>
if (displayspecificCases.imageurl)
displayspecificCases.imageurl.split(",").forEach((item, i) =>
console.log(item);
if (item !== "")
firebase
.storage()
.ref()
.child(item)
.getMetadata()
.then((results) =>
// Construct complete image URL
const url = `https://firebasestorage.googleapis.com/v0/b/$
results.bucket
/o/$encodeURIComponent(item)?alt=media`;
console.log("i is :" + i);
try
// Update state array at index i
setObjUrl((objOfUrl) =>
objOfUrl.map((objUrl, index) => (index === i ? url : objUrl))
);
catch (e)
console.log("err is in view useEffect try catch e : " + e);
)
.catch((err) =>
console.log(err);
);
);
, [displayspecificCases]);
// Log state when it updates
useEffect(() =>
console.log(objOfUrl); //console logs [0: "url.....", 1: "url....."]
, [objOfUrl]);
【讨论】:
感谢您的解决方案,不幸的是,要么我在某个地方搞砸了,要么问题不在于您提供的解决方案。实现代码后,我仍然遇到同样的问题,即页面仅显示 1 张图像。我强烈怀疑问题在于 JSX 以及我如何尝试渲染图像。但对于我的生活,我似乎无法找到另一种方式来渲染它。 另外,另一个问题,在 //Update state array at index i 下。我不完全理解 try-catch 块试图实现什么,在匿名函数中,参数 objOfUrl 是空的,那么 .map 将如何与之交互? @daph99 您能否尝试创建一个 running 代码框来重现该问题并将其链接到您的问题中(并在此处 ping @我)?对于第二个问题,objOfUrl
是一个数组,所以当您循环分割图像 urls 数组时,您正在构建这个状态数组。该地图是必要的,因为当firebase调用解析时无法保证顺序,因此您需要索引来匹配元素。我也不太明白为什么在状态更新时会有一个 try/catch,但是你原来的 sn-p 有它,所以我认为它在那里是有原因的。
我认为你是对的,但我太笨了,无法理解,直到有人坐下来向我解释。非常感谢您的帮助!【参考方案2】:
已解决
解决方案说明如下
useEffect(()=>
axios
.get("http://localhost:9998/api/v1/fault/" + lastURLSegment)
.then(async (response) =>
setDisplay(response.data)
const imagesToConstruct = await response.data.imageurl.slice(0,-1).split(",")
// console.log(imagesToConstruct)
imagesToConstruct.length > 0 && imagesToConstruct.forEach((item, i) =>
if (item !== "")
firebase
.storage()
.ref()
.child(item)
.getMetadata()
.then((results) => //main solution here
setImages((prevImages) => [...prevImages, `https://firebasestorage.googleapis.com/v0/b/$results.bucket/o/$encodeURIComponent(item)?alt=media`])
).catch((err) =>
console.log(err);
);
)
)
, [])
问题
每次调用 useEffect 时,构造的 url 都会被解析成一个临时数组 (objOfUrl) 使用 setobjUrl(objOfUrl) setState 到 objUrl 但是,由于某种原因,我无法弄清楚为什么它会覆盖状态并且状态仅以一个构造的 URL 结束。所以我不得不咨询某人来帮助我编写代码,这就是他提供的解决方案。
解决方案说明 将 2 个 useEffect 压缩为 1,然后使用扩展运算符设置新状态 (images)。
感谢那些试图提供帮助并回复此帖子的人!
【讨论】:
以上是关于即使 .map 循环通过数组的所有索引,也无法在我的 React 应用程序中的 array.map 中显示我的 JSX 中的图像的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:即使 userData 是数组,userData.map 也不是函数
JavaScript的map循环forEach循环filter循环
CLion无法解析类型std :: unordered_map,即使它提示我包含标题和编译工作