简体   繁体   English

无法从我的数组中显示我的 JSX 中的图像。map 在我的反应应用程序中,即使。map 循环通过数组的所有索引

[英]Cannot display images in my JSX from my array.map in my react app even though .map loops though all index of array

The question : why doesn't react display my image s in the JSX?问题:为什么不响应在 JSX 中显示我图像? How can I get it to display the image s ?我怎样才能让它显示图像s

Edit: the issue I suspect is not with the way I get the data but rather the way I try to display/render the image, which I have labeled under main issue below.编辑:我怀疑的问题不是我获取数据的方式,而是我尝试显示/渲染图像的方式,我在下面的主要问题下标记了它。

I have a functional component that has a useEffect to GET a JSON object from firebase.我有一个具有 useEffect 的功能组件,可以从 firebase 获取 JSON object。

useEffect(()=>{
        axios
        .get("http://localhost:9998/api/v1/fault/" + lastURLSegment)
        .then((response) => {
            setDisplay(response.data)
        })
    },[])

Then I extract the imageURL value and query firebase to return me a url viewable on the web eg https://firebasestorage.googleapis.com/v0/b/${results.bucket}/o/${encodeURIComponent(item)}?alt=media Then I extract the imageURL value and query firebase to return me a url viewable on the web eg https://firebasestorage.googleapis.com/v0/b/${results.bucket}/o/${encodeURIComponent(item)}? alt=媒体

once I am able to get the URL for the image, I setState into an array called objUrl一旦我能够获得图像的 URL,我将 setState 放入一个名为 objUrl 的数组中

edit: there is objOfUrl and objUrl, objOfUrl is a var [], objOfUrl is a state编辑:有 objOfUrl 和 objUrl,objOfUrl 是一个 var [],objOfUrl 是一个 state

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)
                        try{setObjUrl(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])

Main issue is here!主要问题在这里! So I want to display the images in JSX.所以我想在 JSX 中显示图像。 So I setState the array into a state and tried to use.map to return each item in the array so I can use img tag to display them所以我将数组设置为 state 并尝试使用.map 返回数组中的每个项目,这样我就可以使用 img 标签来显示它们

// inside the JSX
{objUrl.map((item, i) => { console.log(i); return <div class="column"> <img key={i} width="360px" height="270px" src={item} alt="no photo"/> </div>})}

But the problem right now is that only 1 image is displayed and not the whole array.但现在的问题是只显示 1 张图像而不是整个数组。 Also whenever it renders, it seems to randomly display one of images inside the array.此外,无论何时渲染,它似乎都会随机显示数组内的一个图像。 How do I display all images inside the array?如何显示数组内的所有图像? many thanks!非常感谢!

sidenote: I know my code is messy, I'm still learning, please do give advice and tips on how to improve certain parts!旁注:我知道我的代码很乱,我还在学习,请就如何改进某些部分提供建议和提示!

If I understand your code correctly it is doing:如果我正确理解您的代码,它正在执行以下操作:

  1. Effect callback triggered by displayspecificCases updating displayspecificCases更新触发的效果回调
  2. Split displayspecificCases.imageurl into array of urlsdisplayspecificCases.imageurl拆分为 url 数组
  3. Call firebase backend for the bucket the image is in for the real image URL为图像所在的桶调用 firebase 后端以获得真实图像 URL

Issues问题

  1. You are mutating your objOfUrl state object.你正在改变你的objOfUrl state object。

     objOfUrl[i] = `https://firebasestorage.googleapis.com/v0/b/${results.bucket}/o/${encodeURIComponent(item)}?alt=media`
  2. You enqueue standard state updates in a loop.您将标准 state 更新排入队列。 This enqueues all state updates using the state value from the previous render cycle (remember state is const ).这将使用上一个渲染周期中的 state 值将所有 state 更新排入队列(请记住 state 是const )。 This is also a problem since objOfUrl IS the state reference.这也是一个问题,因为objOfUrlstate 参考。 It should be a new array reference.应该是一个新的数组引用。

     setObjUrl(objOfUrl)
  3. I suppose this isn't a cause for your issue, but it is incorrect to use array.prototype.map to issue array side-effects.我想这不是您的问题的原因,但是使用array.prototype.map发出数组副作用是不正确的。

Solution解决方案

Use a functional state update to使用功能 state 更新到

  1. Correctly enqueue state updates in a loop在循环中正确地将 state 更新排入队列
  2. Correctly return a new state array reference正确返回新的 state 数组引用

Code代码

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]);

Solved解决了

solution explained below 解决方案解释如下

 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); }), } }) }) }, [])

The issue问题

Every time useEffect is called, the constructed url is parsed into a temp array (objOfUrl) which is setState into objUrl by using setobjUrl(objOfUrl) However, for some reason, i cannot figure out why it overwrites the state and the state only ends up with one constructed URL. Every time useEffect is called, the constructed url is parsed into a temp array (objOfUrl) which is setState into objUrl by using setobjUrl(objOfUrl) However, for some reason, i cannot figure out why it overwrites the state and the state only ends up带有一个构造的 URL。 So i had to consult someone to help with my code and this was the solution he provided. 所以我不得不咨询某人来帮助我编写代码,这就是他提供的解决方案。

The solution explained Compressed the 2 useEffect into 1 and then set new state (images) using the spread operator.该解决方案解释了将 2 useEffect 压缩为 1,然后使用扩展运算符设置新的 state (图像)

Thank you to those who have attempted to help and replied to this post!感谢那些试图帮助并回复此帖子的人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM