刚刚开始学习反应,并且需要一些有关如何循环遍历对象并将值传递到axios get请求的指针,然后将数据存储并呈现在屏幕上。
我有多个对象的数组,如下所示:
const albums = [
{
artist: 'Artist 1',
album: 'Album 1'
},
{
artist: 'Artist 2',
album: 'Album 2'
},
{
artist: 'Artist 3',
album: 'Album 3'
}
];
我想遍历相册并将这些值传递给Last.fm API的axios GET请求:
fetchAlbum(artist, title) {
axios.get(`https://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=API_KEY&artist=${artist}&album=${title}&format=json`)
.then(res => {
// ...
})
}
componentDidMount() {
this.fetchAlbum('Artist 1','Album 1');
this.fetchAlbum('Artist 2','Album 2');
this.fetchAlbum('Artist 3','Album 3');
}
响应返回的数据(特别是相册图像URL)是我想要用来创建相册网格(呈现为组件)的数据。我是否需要将所有这些响应数据推入状态,然后遍历并从那里渲染?还是有更简单的方法?在此先感谢!
答案 0 :(得分:1)
为了同时请求多个API,可以使用axios.all函数。有关更多详细信息,请参见this link。我提供了一个基本的伪代码,以说明我们如何完成您的要求。请参考这个例子。如果您想进一步澄清,可以询问。
您可以参考this post检查setState的工作方式。
/* Basic Example */
class App extends React.Component {
albums = [];
baseUrl = `https://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=API_KEY`;
constructor(props) {
super(props);
this.albums = [{artist: "Artist 1",album: "Album 1"}, ..... ]
this.state = {
imageUrls: []
}
}
componentDidMount() {
axios.all(this.albums.map(u => axios.get(`{this.baseUrl}&artist=${u.artist}&album=${u.album}&format=json`)))
.then(axios.spread((...res) => {
// all requests are now complete
console.log(res);
//note res[0] will include first response, res[1] will include second response
//now you need to manipulate data as you required in state
const imgUrls = this.manipulationFunc(res);
this.setState(() => {
return {imageUrls: imgUrls }
})
}));
}
manipulationFunc(data) {
// process image url in each response and return it
let imageUrls = [];
imageUrls = getImageUrlsFromDataUsingLoopOrMap;
return imageUrls ;
}
render() {
const {imageUrls} = this.state
const elem = imageUrls && imageUrls[0] ?
(imageUrls.map(url => (
<img src={url} />
)): null;
return <div> {{elem}} </div>;
}
}
我还没有在实际的编辑器中完成它。在出现语法错误的情况下致歉。
答案 1 :(得分:0)
您可以执行类似的操作,但是可以。您可能希望在组件状态下设置这些变量,或者在用componentWillMount()
加载组件之前获取它们,然后将其设置为您的状态。这是
import React, { Component, Fragment } from "react";
import { AlbumComponent } from "/components/album";
export class ParentContainer extends Component {
constructor() {
super();
this.state = {
albums: [
{
artist: "Artist 1",
album: "Album 1"
},
{
artist: "Artist 2",
album: "Album 2"
},
{
artist: "Artist 3",
album: "Album 3"
}
],
isLoading: true
};
}
componentWillMount() {
this.state.albums.forEach(album => this.fetchAlbum(album));
}
fetchAlbum = album => {
axios
.get(
`https://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=API_KEY&artist=${
album.artist
}&album=${album.title}&format=json`
)
.then(res => {
let newState = Object.assign({}, this.state); // Duplicate your state so requests can be pushed in an array cleanly
newState.albumMeta.push(res.data); // push the returned object to the array
this.state.albums.length === newState.albums.length
? !newState.isLoading
: newState.isLoading;
this.setState(newState);
})
.catch(err => {
console.log(error);
});
};
render() {
return (
<Fragment>
{!this.state.isLoading &&
this.state.albumMeta.map(album => <AlbumComponent album={album}/>)}
// Render your view out here based on if data is loaded
</Fragment>
);
}
}