开发者问题收集

我不明白为什么我在 React 中收到错误“无法读取未定义的属性‘map’”

2021-03-04
78

我尝试将信息从数据库加载到我的 React App。除了我正在运行的 map 函数之外,一切都按预期工作。我试图在 div 中列出给定电影的所有类型。

import React, { Component } from 'react';
import axios from 'axios';
import ReactPlayer from 'react-player';
import play from '../../img/play-icon.svg';
import './hero-display.scss';

class HeroDisplay extends Component {
    constructor() {
        super();

        this.state = {
            movie: {},
            trailer: false
        }
    }

    componentDidMount() {
        axios.get('https://petflix.herokuapp.com/movie')
            .then((response) => {
                this.setState({
                    movie: response.data
                })
            })
            .catch((error) => {
                console.error(error);
            });
    }

    openTrailer = () => {
        this.setState({
            trailer: true
        });
    }

    closeTrailer = () => {
        this.setState({
            trailer: false
        });
    }

    render() {
        const { movie, trailer } = this.state;
        return (
            <>
                <div className="hero-display__container" style={{backgroundImage: `url(${movie.backdropURL})`}}>
                    <div className="hero-display__movie-information">
                        <img className="hero-display__movie-logo" src={movie.logoURL} alt=""/>
                        <h1 className="hero-display__heading">Watch Now</h1>
                        <p className="hero-display__movie-description">{movie.description}</p>
                        <div className="hero-display__control-buttons">
                            <button onClick={this.openTrailer} className="hero-display__button play">
                                <img src={play} alt=""/>
                                Play Trailer
                            </button>
                        </div>
                    </div>
                    <div className="hero-display__rating">
                        <p>{movie.rating}</p>
                    </div>
                </div>
                <div className={trailer ? "movie__trailer showing" : "movie__trailer hidden"}>
                    <div className="movie-trailer__container">
                        <button className="movie-trailer__close-button" onClick={this.closeTrailer}></button>
                        <ReactPlayer className="video-player" light={movie.backdropURL} volume={0} loop={true} playing={true} image={movie.backdropURL} muted={false} url={movie.trailerURL}/>
                        <div className="movie__information">
                            <div className="movie-trailer__title-add">
                                <h1 className="movie-trailer__title">{movie.title}</h1>
                                <button className="movie-trailer__button"></button>
                            </div>
                            <p className="movie-trailer__rating">{movie.rating}</p>
                            <p className="movie-trailer__director">Directed By: {movie.director}</p>
                            <p className="movie-trailer__description">{movie.description}</p>
                            {movie.genres.map((genre) => {
                                return (
                                    <p className="movie-trailer__genres">{genre}</p>
                                )
                            })}
                        </div>
                    </div>
                </div>
            </>
        )
    }
}

export default HeroDisplay;

当状态作为 prop 传递时,map 函数在不同的功能组件中工作,但不在类组件本身中工作。非常感谢您的帮助。

存储在状态中的电影对象的示例。

{
  "title": "101 Dalmatians",
  "description": "A brave young man is thrust into adulthood as he and his courageous team of sled dogs embark on a grueling and treacherous cross-country marathon.",
  "director": "Stephen Herek",
  "genres": [
      "Adventure",
      "Family",
      "Comedy"
  ],
  "rating": "G",
  "backdropURL": "https://www.themoviedb.org/t/p/original/mz75dVXfen4J1Z0R8DbTenXNywz.jpg",
  "posterURL": "https://www.themoviedb.org/t/p/original/8o2ADoAyG796UwTjwBFjPyBz0yG.jpg",
  "trailerURL": "https://www.themoviedb.org/video/play?key=K2CTJS12RdI",
  "logoURL": "https://www.themoviedb.org/t/p/original/noruOCRUoWndPPDPJYdR7kVsiq5.png"
}
2个回答

发生这种情况的原因是,在 api 调用之前, movie 状态的 generes 属性不可用。

因此,不要直接访问属性。

  {movie.genres.map((genre) => {
       return (
          <p className="movie-trailer__genres">{genre}</p>
      )
   })}

使用可选链接和 ?。

  {movie?.genres?.map((genre) => {
       return (
          <p className="movie-trailer__genres">{genre}</p>
      )
   })}
Malay M
2021-03-04

此部分:

      {movie.genres.map((genre) => {
           return (
              <p className="movie-trailer__genres">{genre}</p>
          )
       })}

应为

      {movie.genres && movie.genres.map((genre) => {
           return (
              <p className="movie-trailer__genres">{genre}</p>
          )
       })}

或者,您可以执行 movie?.genres?.map((genre) => {...

否则 movie.genres 在第一次渲染时未定义。

codemonkey
2021-03-04