ReactJS:渲染图像数组

ReactJS: Rendering an array of images

我还是 ReactJS 的新手,我目前正在摆弄 Spotify API,它工作得很好,但我在尝试渲染通过 API。 起初,我尝试在 render() 组件中调用它,但它只生成一个空 'undefined' 图像列表,只显示 alt 属性。其次,我在里面试了一下return()和前者一样的症状,这次完全没有任何图像。

这个问题只会在我尝试使用 .map() 方法时出现;当我单独渲染图像时,它工作得很好。

import React, { Component } from "react";

let someData = "hello";

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      playlists: { name: [], plist_id: [], albumArt: [] }
    };
  }

  getPlaylists(someData) {
    let plistNames = [];
    let plistContents = [];
    let plistArts = [];

    someApi
      .searchPlaylists(someData)
      .then(data => {
        if (data.playlists.items) {
          if (data.playlists.items.length > 0) {
            console.log(data);
            data.playlists.items.forEach(plist => {
              plistNames.push(plist.name);
              plistContents.push(plist.id);
              plistArts.push(plist.images[0].url);

              this.setState({
                playlists: {
                  name: plistNames,
                  plist_id: plistContents,
                  albumArt: plistArts
                }
              });
            });
          }
        }
      })
      .catch(err => {
        console.error(err);
      });
  }

  render() {
    //Produces a list of empty images with only the alt attribute showing up
    let _playlists = this.state.playlists.albumArt.map((plist, index) => {
      return <img key={index} src={plist.albumArt} alt="Album Art"/>
    })
  return (
      <div className="App">
        <button onClick={() => this.getPlaylists(someData)}>
          Get Playlist
        </button>

      {_playlists}

      {/*  THIS PRODUCES a similar sympton as the former
          {playlists.albumArt.map((plist, index) => {
              <img key={index}  src={plist.albumArt} alt="Album Art"/>
              })
          } */}

      {/*  THIS IMAGE RENDERS THE FIRST ELEMENT FROM THE ARRAY AND WORKS FINE
            <img src={playlists.albumArt[0]}/> */}

      </div>
    );
  }
}

如何解决这样的问题?非常感谢您的时间和帮助。

条件内联语句呢?这样它接收到信息后会渲染?

    {this.state.playlist.name ?  
    //have your code here to display
    :
    <LoadingSpinner />
}

我不能肯定地说,因为我需要查看返回数据的结构,但我相当有信心您想要在其中设置状态forEach() 循环了很多次。

相反,您可能希望映射数据结果并将其转换为一些有用的对象数组,然后再将其添加到状态,以便您可以在 render 中映射它(看起来不错)并可预测地访问内容。

话虽如此,我希望 searchPlaylists 调用后的 .then() 块看起来更像:

const playlistsWrangled =  data.playlists.items.map(plist => ({ 
  name: plist.name, 
  plist_id: plist.id, 
  albumArt: plist.images[0].url 
}));

this.setState({ playlists: wrangledPlaylists });

我认为你的两种情况的区别在于,在 "working" 一种情况下,你没有 alt 道具。

如果您希望图像在加载过程中清晰显示,则必须走捷径。要么使用为您逐步处理图像加载的模块,要么,如果您不关心可访问性,请将 alt 标签设为空并为图像提供默认背景颜色(如果您愿意,可以在加载后设置 alt 标签)。

您目前正在使用以下方式映射您的专辑封面数组:

let _playlists = this.state.playlists.albumArt.map((plist, index) => {
  return <img key={index} src={plist.albumArt} alt="Album Art"/>
})

问题是您将 <img /> 标签的 src 设置为 plist.albumArt,而实际上“plist”的值是您想要的 url:

let _playlists = this.state.playlists.albumArt.map((plist, index) => {
  return <img key={index} src={plist} alt="Album Art"/>
})

正如其他人提到的,也不建议在循环期间设置状态。而是 loop/map 遍历数据并将其存储在一个局部变量中,您可以使用该变量调用一次 setState。