Reactjs 无法访问Api调用数据。返回未定义的。反应

Reactjs 无法访问Api调用数据。返回未定义的。反应,reactjs,themoviedb-api,Reactjs,Themoviedb Api,我正在尝试使用React制作一个电影搜索应用程序,并对电影数据库API进行了API调用。我试图做的是获取新电影发行版的数据,但随后进行另一个API调用以获取每个新发行版的具体细节,因为这些数据存储在不同的位置 我可以从第一个API调用访问数据,但当我尝试从第二个数据对象访问电影标记行时,控制台输出“无法读取未定义的属性‘标记行’” App.js class App extends Component { constructor(props) { super(props)

我正在尝试使用React制作一个电影搜索应用程序,并对电影数据库API进行了API调用。我试图做的是获取新电影发行版的数据,但随后进行另一个API调用以获取每个新发行版的具体细节,因为这些数据存储在不同的位置

我可以从第一个API调用访问数据,但当我尝试从第二个数据对象访问电影标记行时,控制台输出“无法读取未定义的属性‘标记行’”

App.js

  class App extends Component {
    constructor(props) {
      super(props)
      this.state = {
        movieRows: [],
        ids: [],
        movieDetails: [],
      }
      this.performSearch = this.performSearch.bind(this);        
    }

    componentDidMount() {
      this.performSearch();
    }

    performSearch() {
      const urlString = "https://api.themoviedb.org/3/movie/popular?api_key=6db3cd67e35336927891a72c05&language=en-US&page=1";
      axios.get(urlString)
        .then(res => {

          const results = res.data.results
          let movieRows = [];
          let movieDetails = [];

          results.forEach((movie) => {

            movieRows.push(movie);
            axios.get(`https://api.themoviedb.org/3/movie/${movie.id}?api_key=6db3cd67e35336927891a72c05&language=en-US`)
            .then(res => {
              movieDetails.push(res.data);
            })
            .catch(function (error) {
              console.log(error);
            });
          });

          this.setState({
            movieRows: movieRows,
            movieDetails: movieDetails,
          });
        })
        .catch(function (error) {
          console.log(error);
        });  
    }
export default class Content extends Component {
    constructor(props) {
        super(props)
        this.state = {
            name: 'Jonathan',
        }
        this.filmLoop = this.filmLoop.bind(this);
    }

    filmLoop() {

        let movieData = this.props.globalState.movieRows;
        let movieDetails = this.props.globalState.movieDetails;

        return movieData.map((movie, index) => {

            return (
                <div className="film" key={index}>
                    <img className="poster" src={`http://image.tmdb.org/t/p/w342${movie.poster_path}`} alt="The Dark Knight poster" />
                    <div className="film-info">
                        <div className="film-title">
                            <h3>{movie.title}</h3>
                        </div>
                        <h4>{movieDetails[index].tagline}</h4>
Content.js

  class App extends Component {
    constructor(props) {
      super(props)
      this.state = {
        movieRows: [],
        ids: [],
        movieDetails: [],
      }
      this.performSearch = this.performSearch.bind(this);        
    }

    componentDidMount() {
      this.performSearch();
    }

    performSearch() {
      const urlString = "https://api.themoviedb.org/3/movie/popular?api_key=6db3cd67e35336927891a72c05&language=en-US&page=1";
      axios.get(urlString)
        .then(res => {

          const results = res.data.results
          let movieRows = [];
          let movieDetails = [];

          results.forEach((movie) => {

            movieRows.push(movie);
            axios.get(`https://api.themoviedb.org/3/movie/${movie.id}?api_key=6db3cd67e35336927891a72c05&language=en-US`)
            .then(res => {
              movieDetails.push(res.data);
            })
            .catch(function (error) {
              console.log(error);
            });
          });

          this.setState({
            movieRows: movieRows,
            movieDetails: movieDetails,
          });
        })
        .catch(function (error) {
          console.log(error);
        });  
    }
export default class Content extends Component {
    constructor(props) {
        super(props)
        this.state = {
            name: 'Jonathan',
        }
        this.filmLoop = this.filmLoop.bind(this);
    }

    filmLoop() {

        let movieData = this.props.globalState.movieRows;
        let movieDetails = this.props.globalState.movieDetails;

        return movieData.map((movie, index) => {

            return (
                <div className="film" key={index}>
                    <img className="poster" src={`http://image.tmdb.org/t/p/w342${movie.poster_path}`} alt="The Dark Knight poster" />
                    <div className="film-info">
                        <div className="film-title">
                            <h3>{movie.title}</h3>
                        </div>
                        <h4>{movieDetails[index].tagline}</h4>
导出默认类内容扩展组件{
建造师(道具){
超级(道具)
此.state={
姓名:'乔纳森',
}
this.filmLoop=this.filmLoop.bind(this);
}
filmLoop(){
让movieData=this.props.globalState.movieRows;
让movieDetails=this.props.globalState.movieDetails;
返回movieData.map((电影,索引)=>{
返回(
{movie.title}
{movieDetails[index].tagline}

*我从最后一行得到了错误。主要问题是,您在
外部调用
setState
。然后
您必须更新
内部的状态,然后
catch
。这是因为
promise
是一个
异步
函数,因此只有当t他已决定不拒绝他的诺言

performSearch(){
常量URL字符串=”https://api.themoviedb.org/3/movie/popular?api_key=6db3cd67e35336927891a72c05&language=en-美国&page=1“;
获取(urlString)
.然后(responsePopular=>{
常量结果=responsePopular.data.results
让movieRows=[];
让movieDetails=[];
结果。forEach((电影)=>{
movieRows=[…movieRows,movie];
axios.get(`https://api.themoviedb.org/3/movie/${movie.id}?api_key=6db3cd67e3536927891a72c05&language=en-US`)
。然后(responseMovie=>{
movieDetails=[…movieDetails,responseMovie.data];
这是我的国家({
电影:电影,
电影详情:电影详情,
})
})
.catch(函数(错误){
console.log(错误);
});
});
})
.catch(函数(错误){
console.log(错误);
});  
}

我认为这可以解决您的问题。

主要的问题是,您在
外部调用
setState
。然后
您必须更新
内部的状态,然后
catch
。这是因为
promise
是一个
异步
函数,因此您只需更改状态当承诺被解决或拒绝时

performSearch(){
常量URL字符串=”https://api.themoviedb.org/3/movie/popular?api_key=6db3cd67e35336927891a72c05&language=en-美国&page=1“;
获取(urlString)
.然后(responsePopular=>{
常量结果=responsePopular.data.results
让movieRows=[];
让movieDetails=[];
结果。forEach((电影)=>{
movieRows=[…movieRows,movie];
axios.get(`https://api.themoviedb.org/3/movie/${movie.id}?api_key=6db3cd67e3536927891a72c05&language=en-US`)
。然后(responseMovie=>{
movieDetails=[…movieDetails,responseMovie.data];
这是我的国家({
电影:电影,
电影详情:电影详情,
})
})
.catch(函数(错误){
console.log(错误);
});
});
})
.catch(函数(错误){
console.log(错误);
});  
}

我认为这可以解决您的问题。

您的设置状态在填充movieDetails之前运行。这当然会导致
movieDetails[index].tagline
失败,因为该索引中没有任何内容。感谢您帮助我理解此问题。现在,在填充movieDetails后,我如何让setState运行?您可以收集阵列中的所有axios承诺,然后使用promise.all来检测它们何时全部完成OK我将尝试一下。几小时后这是我努力的结果。现在我觉得我更了解承诺了。谢谢凯文!你的设置状态在movieDetails填充之前运行。这当然会导致
movieDetails[index].tagline
失败,因为该索引中没有任何内容。感谢您帮助我理解此问题。现在,在填充movieDetails后,我如何让setState运行?您可以收集阵列中的所有axios承诺,然后使用promise.all来检测它们何时全部完成OK我将尝试一下。几小时后这是我努力的结果。现在我觉得我更了解承诺了。谢谢凯文!