我正在关注有关React的在线课程,并且正在使用API​​(swapi.co)进行练习。我们的目标是使用API​​并制作一个可以满足我们需求的React应用。

因此,我试图制作一个具有输入的应用程序,并且每次输入更改时,它都会通过API获取匹配的字符并显示有关该字符的数据。数据之一是角色所在的电影的名称,因此它是一个包含一个或多个字符串的数组。一切顺利,直到我尝试遍历该数组以显示为止。它将console.log整个数组,但不会使用foreach遍历整个数组。

这是我的结果部分:

class ResultPeople extends Component {
constructor() {
    super()
    this.state = {
        movieTitles: []
    }
}
getMovies(movies) {
    var movieTitleList = [];
    movies.forEach(element => {
        fetch(element)
        .then(resp => resp.json())
        .then(movieData => {
            movieTitleList.push(movieData.title);
        })
    });
    this.setState({movieTitles: movieTitleList});
    console.log('getMovies Done');
}
render() {
    const { resultdata } = this.props;
    const { name, films } = resultdata;
    return (
        <div className="result-characters text-white">
            <h2>{name}</h2>
            {films ? <button onClick={() => this.getMovies(films)}>See movies</button> : ''}
            {
                this.state.movieTitles ? <MovieList movies={this.state.movieTitles} /> : null
            }
        </div>
    );
}


}

这是电影列表:

const MovieList = ({ movies }) => {
return (
    <ul>
        {console.log(movies)}
        {
            movies.forEach(element => {
                return <li>{element}</li>;
            })
        }
    </ul>
);


}

我不知道为什么会这样。 console.log(movies)效果很好(尽管取决于记录不同数量电影的时间,可能是因为API?)。但是foreach没有。

这里的错误在哪里?
谢谢 !

最佳答案

您进行了一系列返回诺言的异步调用,并且需要等待它们全部完成后再设置状态。

使用Array.map()迭代影片,进行提取调用,并返回承诺。等待所有的诺言完成使用Promise.all(),然后设置状态。

示例(未经测试):

getMovies(movies) {
  Promise.all(movies.map(element =>
    fetch(element)
    .then(resp => resp.json())
    .then(movieData => movieData.title)
  )).then(movieTitles => this.setState({ movieTitles }))
}


您也可以在组件中使用Array.map(),因为您可以从Array.forEach()返回。

注意:key应该是唯一的。在此示例中,我使用了元素本身,但是如果它们不是唯一的,则需要生成一个唯一的键。

const MovieList = ({ movies }) => (
  <ul>
  {
    movies.map(element => (
      <li key={element}>{element}</li>;
    ))
  }
  </ul>
);

09-20 22:47