Что я хочу сделать, так это то, что при нажатии на конкретный фильм откроется новая страница, где будут представлены изображение фильма, обзор, название и средний балл для этого конкретного фильма.
Я использую базу данных TMDB, и я успешно сделал так, чтобы она отображала фильмы с самым высоким рейтингом. Мой самый большой вопрос: как передать определенные параметры этого фильма (каждый фильм имеет определенный идентификатор) другому методу.
Вот мой код на данный момент -> MoviesComponent.dart:
import React from "react";
const IMG_API="https://image.tmdb.org/t/p/w1280/";
const Movie =({title, poster_path, backdrop_path, vote_average})=>
(
<div className="movie">
<img src={IMG_API+poster_path} alt={backdrop_path}/>
<div className="info">
<h3>{title}</h3>
<span>{vote_average}</span>
</div>
</div>
);
export default Movie;
И Movies.dart, где все показано (отредактировано):
import {useEffect, useState} from 'react';
import { Link } from 'react-router-dom';
import Movie from './components/MovieComponent';
import Logo from './assets/chillax2.svg';
import MovieDetails from './MovieDetail';
//due to it being a demo project I will not safe keep the API
const SEARCH_API="https://api.themoviedb.org/3/search/movie?api_key=89eef3426d167c3c8145a257ebe68357&query=";
const TOP_RATED_API="https://api.themoviedb.org/3/movie/top_rated?api_key=89eef3426d167c3c8145a257ebe68357&page=1"
function Movies() {
const [movies, setMovies] = useState([]);
const [id, setID] = useState('');
const [searchTerm, setSearchTerm] = useState('');
useEffect(()=>{
fetch(TOP_RATED_API)
.then((res)=>res.json())
.then((data)=>{
console.log(data);
setMovies(data.results);
setID(data.results)
});
},[]);
const handleOnSubmit= (e)=> {
e.preventDefault();
if(setSearchTerm){
fetch(SEARCH_API+searchTerm)
.then((res)=>res.json())
.then((data)=>{
console.log(data);
setMovies(data.results);
});
setSearchTerm('');
}
}
const handleOnChange= (e)=> {
setSearchTerm(e.target.value);
}
const details= Movies.filter((movie) => movie.id === id);
return(
<>
<header>
<form onSubmit={handleOnSubmit}>
<img href="/" className="logo" src={Logo}></img>
<div className="nav-bar-button">
<a href="/Movies" className="film">Movies</a>
<a href="/TVShows" >TV Shows</a>
<input className="search-bar" type="search" placeholder="Search" value={searchTerm} onChange={handleOnChange}/>
</div>
</form>
</header>
<div className="container" onClick={MovieDetails(details)}>
{movies.length && movies.map((movie)=>
<Movie key={movie.id} {...movie} />)}
</div>
</>
);
}
export default Movies;
Здесь также MovieDetailsComponent.dart:
import React from "react";
const IMG_API="https://image.tmdb.org/t/p/w1280/";
const MovieDetail =({title, poster_path, backdrop_path, vote_average, overview})=>
(
<div className="movie">
<img src={IMG_API+poster_path} alt={backdrop_path}/>
<div className="info">
<h3>{title}</h3>
<span>{vote_average}</span>
<p>{overview}</p>
</div>
</div>
);
export default MovieDetail;
И MovieDetails.dart:
import {useEffect, useState} from 'react';
import { Link } from 'react-router-dom';
import MovieDetail from './components/MovieDetailComponents';
import Logo from './assets/chillax2.svg';
//due to it being a demo project I will not safe keep the API
const SEARCH_API="https://api.themoviedb.org/3/search/movie?api_key=89eef3426d167c3c8145a257ebe68357&query=";
const TOP_RATED_API="https://api.themoviedb.org/3/movie/top_rated?api_key=89eef3426d167c3c8145a257ebe68357&page=1"
function MovieDetails() {
const [movies, setMovies] = useState([]);
const [id, setID] = useState('');
useEffect(()=>{
fetch(TOP_RATED_API)
.then((res)=>res.json())
.then((data)=>{
console.log(data);
setMovies(data.results);
});
},[]);
return(
<>
<header>
<img href="/" className="logo" src={Logo}></img>
<div className="nav-bar-button">
<a href="/Movies" className="film">Movies</a>
<a href="/TVShows" >TV Shows</a>
</div>
</header>
<div>
{movies.length && movies.map((movie)=>
<MovieDetail key={movie.id} {...movie}/>)}
</div>
</>
);
}
export default MovieDetails;
import {useEffect, useState} from 'react';
import { Link } from 'react-router-dom';
import MovieDetail from './components/MovieDetailComponents';
import Logo from './assets/chillax2.svg';
//due to it being a demo project I will not safe keep the API
const SEARCH_API="https://api.themoviedb.org/3/search/movie?api_key=89eef3426d167c3c8145a257ebe68357&query=";
const TOP_RATED_API="https://api.themoviedb.org/3/movie/top_rated?api_key=89eef3426d167c3c8145a257ebe68357&page=1"
function MovieDetails() {
const [movies, setMovies] = useState([]);
const [id, setID] = useState('');
useEffect(()=>{
fetch(TOP_RATED_API)
.then((res)=>res.json())
.then((data)=>{
console.log(data);
setMovies(data.results);
});
},[]);
return(
<>
<header>
<img href="/" className="logo" src={Logo}></img>
<div className="nav-bar-button">
<a href="/Movies" className="film">Movies</a>
<a href="/TVShows" >TV Shows</a>
</div>
</header>
<div>
{movies.length && movies.map((movie)=>
<MovieDetail key={movie.id} {...movie}/>)}
</div>
</>
);
}
export default MovieDetails;
Как я уже говорил ранее, создание модального окна не является сложной задачей, меня беспокоит то, как передать эти конкретные параметры (фильма, на который я нажимаю) функции/объекту, чтобы я мог их использовать. подробности (название, картинка, обзор) в нем.
Заранее спасибо за все советы и полезные комментарии. :D
Эммм, как мне это сделать. Хорошо, создать состояние для одного фильма несложно: const [movies, setMovies] = useState([]); Но как передать его идентификатор?
Я обновил свой вопрос, я не совсем уверен, куда поместить эти элементы, поэтому вы можете мне помочь, также прямо сейчас, как и код, он отображает эту ошибку: TypeError: Movies.filter не является функцией
Я полагаю, что он хотел написать movie.filter (со строчной буквой «м»), а не Movies.filter. Причина: фильмы — это массив, к которому мы хотели применить фильтр, а .filter — это функция только для массивов, поэтому исправление этого исправит TypeError. Примечание. Если «id» уникален для каждого фильма (как вы сказали), лучше использовать .find вместо .filter, поскольку .find даст вам точный объект, из которого вы можете использовать детали (название, изображение, .etc) вместо массива (и он перестанет выполняться, как только он совпадет) Еще лучше (для большего массива) преобразование ваш массив в объект по идентификатору и напрямую используйте MoviesMap[id]