I'm building an movie app in react using router v6. Here there are several pages. From the home screen when I click on a move poster it takes me to the move details page(/movie-detail/242) and it works fine. Inside the movie details page I have used the same poster component like in the home page to show similar movies like the current move. But here when I click on a movie poster the URL ID changes (/movie-detail/1045), but the new move detailenter code here is not loaded.
In short I'm trying to access a moveDetail Page with in a moveDetail page.
Please Help Me.. Thank you
App.js File
import React, { useEffect } from "react";
import "./App.css";
import HomeScreen from "./screens/HomeScreen";
import { BrowserRouter, Routes, Route, Link, Outlet } from "react-router-dom";
import LoginScreen from "./screens/LoginScreen";
import { auth } from "./firebase";
import { useDispatch, useSelector } from "react-redux";
import { login, logout, selectUser } from "./features/userSlice";
import ProfileScreen from "./screens/ProfileScreen";
import MovieDetail from "./movieDetail/MovieDetail";
import LoadingSpinner from "./LoadingSpinner";
import AppError from "./UI/AppError";
import SearchHome from "./search/SearchHome";
function App() {
const user = useSelector(selectUser);
const dispatch = useDispatch();
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((userAuth) => {
if (userAuth) {
//Logged in
dispatch(
login({
uid: userAuth.uid,
email: userAuth.email,
})
);
} else {
//Logged out
dispatch(logout());
}
});
return unsubscribe;
}, [dispatch]);
return (
<div className="app">
{!user ? (
<LoginScreen />
) : (
<Routes>
<Route path="/profile" element={<ProfileScreen />} />
<Route path="/" element={<HomeScreen />} />
<Route path="/search" element={<SearchHome />} />
<Route path="/movie-detail/:movieId" element={<MovieDetail />} />
<Route path="*" element={<AppError />} />
</Routes>
)}
</div>
);
}
export default App;
Index.js File
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import store from "./app/store";
import { Provider } from "react-redux";
import * as serviceWorker from "./serviceWorker";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
serviceWorker.unregister();
//HomeScreen
import React, { useEffect } from "react";
import Banner from "../Banner";
import "./HomeScreen.css";
import Nav from "../Nav";
import Row from "../Row";
import requests from "../Requests";
import Footer from "../Footer";
import RowLarge from "../RowLarge";
function HomeScreen(props) {
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<div className="homeScreen">
<Nav />
<Banner />
<RowLarge
title="NETFLIX ORIGINALS"
fetchUrl={requests.fetchUpcoming2}
isLargeRow
/>
<Row title="Trending Now" fetchUrl={requests.fetchTrending} />
<Row title="Top Rated" fetchUrl={requests.fetchTopRated} />
<Row title="Upcoming" fetchUrl={requests.fetchUpcoming3} />
<Row title="Action Movies" fetchUrl={requests.fetchActionMovies} />
<Row title="Comedy Movies" fetchUrl={requests.fetchComedyMovies} />
<Row title="Horror Movies" fetchUrl={requests.fetchHorrorMovies} />
<Row title="Romance Movies" fetchUrl={requests.fetchRomanceMovies} />
<Row title="Documentaries" fetchUrl={requests.fetchDocumentaries} />
<Footer />
</div>
);
}
export default HomeScreen;
Movie Details Page
import axios from "axios";
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import Footer from "../Footer";
import Nav from "../Nav";
import Blocker from "../UI/Blocker";
import MovieBanner from "./MovieBanner";
import "./MovieDetail.css";
import MoviePoster from "./MoviePoster";
import MovieTag from "./MovieTag";
import Row from "../Row";
import requests from "../Requests";
import MovieAbout from "./MovieAbout";
import MovieComingSoon from "./MovieComingSoon";
import MovieVideo from "./MovieVideo";
import MovieSimilar from "./MovieSimilar";
import MovieCast from "./MovieCast";
import MovieReview from "./MovieReview";
import LoadingSpinner from "../LoadingSpinner";
function MovieDetail() {
const { movieId } = useParams();
const [movie, setMovie] = useState(null);
const API_KEY = "################################";
useEffect(() => {
axios
.get(
`https://api.themoviedb.org/3/movie/${movieId}?api_key=${API_KEY}&language=en-US`
)
.then((res) => {
setMovie(res.data);
})
.catch((err) => {
console.log(err);
});
}, []);
//scroll to top each time this component is mounted
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<>
{movie ? (
<div>
<Nav />
<MovieBanner movie={movie} />
<MovieTag />
<MovieCast movieId={movieId} apiKey={API_KEY} />
<MoviePoster movie={movie} />
<MovieAbout movie={movie} />
<MovieVideo movie={movie} movieId={movieId} apiKey={API_KEY} />
<MovieReview movieId={movieId} apiKey={API_KEY} />
<MovieSimilar movieId={movieId} apiKey={API_KEY} />
<MovieComingSoon apiKey={API_KEY} />
<Footer />
</div>
) : (
<LoadingSpinner />
)}
</>
);
}
export default MovieDetail;
//Reused Poster Component
import { render } from "@testing-library/react";
import React, { useEffect, useRef, useState } from "react";
import { useNavigate } from "react-router-dom";
import axios from "./axios";
import "./Row.css";
function Row({ title, fetchUrl, isLargeRow = false }) {
const [movies, setMovies] = useState([]);
const postersRef = useRef(0);
const [scrollPossition, setScrollPossition] = useState(0);
const navigate = useNavigate();
//left right horizontal scroll
const scroll = (scrollOffset) => {
postersRef.current.scrollLeft += scrollOffset;
};
const setLeftArrowVisibility = () => {
let scrollPossitionValue = postersRef.current.scrollLeft;
setScrollPossition(scrollPossitionValue + 600);
};
const setRightArrowVisibility = () => {
let scrollPossitionValue = postersRef.current.scrollLeft;
setScrollPossition(scrollPossitionValue - 600);
};
const base_url = "https://image.tmdb.org/t/p/original/";
useEffect(() => {
async function fetchData() {
const request = await axios.get(fetchUrl);
setMovies(request.data.results);
return request;
}
fetchData();
}, [fetchUrl]);
const renderLeftArrow = () => {
if (scrollPossition > 0) {
return (
<svg
onClick={() => {
scroll(-600);
setRightArrowVisibility();
}}
viewBox="0 0 18 18"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="currentColor"
d="M11.56 5.56L10.5 4.5 6 9l4.5 4.5 1.06-1.06L8.12 9z"
></path>
</svg>
);
}
};
const renderRightArrow = () => {
if (scrollPossition <= 3000) {
return (
<svg
onClick={() => {
scroll(600);
setLeftArrowVisibility();
}}
viewBox="0 0 18 18"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="currentColor"
d="M11.56 5.56L10.5 4.5 6 9l4.5 4.5 1.06-1.06L8.12 9z"
></path>
</svg>
);
}
};
return (
<div className="row">
<h2>{title}</h2>
<div ref={postersRef} className="row__posters">
<div className="row__arrow-left">{renderLeftArrow()}</div>
{movies.map(
(movie) =>
((isLargeRow && movie.poster_path) ||
(!isLargeRow && movie.backdrop_path)) && (
<div
key={movie.id + Math.random() - Math.random()}
className="row__imageContainer"
>
<img
className={`row__poster`}
src={`${base_url}${
isLargeRow ? movie.poster_path : movie.backdrop_path
}`}
alt={movie.name}
/>
<div
className="row__imageOverlay"
onClick={() => {
navigate(`/movie-detail/${movie.id}`);
}}
>
<div className="row__overlayText">
<p> {movie?.vote_average}</p>
<p>IMDB Rating</p>
</div>
</div>
<div className="row__movieName">
{" "}
{movie?.title || movie?.name || movie?.original_name}
</div>
</div>
)
)}
<div className="row__arrow-right">{renderRightArrow()}</div>
</div>
</div>
);
}
export default Row;