Я не понимаю, почему я получаю сообщение об ошибке «Не удается прочитать свойство ‘map’ неопределенного» в React

#arrays #reactjs #dictionary #state

#массивы #reactjs #словарь #состояние

Вопрос:

Я пытаюсь загрузить информацию из базы данных в мое приложение React. Все работает как ожидалось, за исключением функции 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;
 

Функция map работает в другом функциональном компоненте, когда состояние передается как prop, но не в самом компоненте класса. Я ценю помощь.

Пример объекта movie, который хранится в состоянии.

 {
  "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"
}
 

Ответ №1:

Это происходит из generes -за того, что свойство movie состояния недоступно перед вызовом api.

Поэтому вместо прямого доступа к свойству.

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

используйте необязательную цепочку с ?.

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

Ответ №2:

Эта часть:

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

Должно быть

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

В качестве альтернативы, вы могли бы сделать movie?.genres?.map((genre) => {...

В противном movie.genres случае не определено при первом рендеринге.