Подробный фильм на новой странице - React

avatar
Don
1 июля 2021 в 17:06
223
1
1

Что я хочу сделать, так это то, что при нажатии на конкретный фильм откроется новая страница, где будут представлены изображение фильма, обзор, название и средний балл для этого конкретного фильма.

Я использую базу данных 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

Источник

Ответы (1)

avatar
Musadiq Khan
1 июля 2021 в 17:12
0

Создать состояние для одного фильма. Как только вы нажмете на какой-либо фильм, получите его идентификатор, отфильтруйте список фильмов по идентификатору и передайте это состояние всплывающему окну.

const [id, setID] = useState('');

Это ваше состояние для ID. Используйте onClik для каждого фильма в списке и установите ID. Затем на его основе отфильтруйте массив фильмов.

Movies.filter((movie) => movie.id === id);

Либо сохраните результат вышеуказанного фильтра в переменной, либо в состоянии и передайте его модальному компоненту.

Don
1 июля 2021 в 17:13
0

Эммм, как мне это сделать. Хорошо, создать состояние для одного фильма несложно: const [movies, setMovies] = useState([]); Но как передать его идентификатор?

Don
1 июля 2021 в 17:39
0

Я обновил свой вопрос, я не совсем уверен, куда поместить эти элементы, поэтому вы можете мне помочь, также прямо сейчас, как и код, он отображает эту ошибку: TypeError: Movies.filter не является функцией

Momin Bin Shahid
1 июля 2021 в 22:07
0

Я полагаю, что он хотел написать movie.filter (со строчной буквой «м»), а не Movies.filter. Причина: фильмы — это массив, к которому мы хотели применить фильтр, а .filter — это функция только для массивов, поэтому исправление этого исправит TypeError. Примечание. Если «id» уникален для каждого фильма (как вы сказали), лучше использовать .find вместо .filter, поскольку .find даст вам точный объект, из которого вы можете использовать детали (название, изображение, .etc) вместо массива (и он перестанет выполняться, как только он совпадет) Еще лучше (для большего массива) преобразование ваш массив в объект по идентификатору и напрямую используйте MoviesMap[id]