#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
случае не определено при первом рендеринге.