I am working on an API project using React-Router-DOM for navigation and when the initial search results are called I have an array of 8 movies that are shown based on a keyword from the user’s search query. Once the user has chosen the specific movie they are looking for by clicking the "SEE MORE" button attached to the movie card it is supposed to redirect to another page that shows specific details about the selected movie, but instead I keep getting uncaught runtime errors that is saying I have an invalid hook call but I’m not sure where I went wrong.
Below is the code that is first used after the original search query :
import axios from "axios";
import React, { useEffect, useState } from "react";
import Nav from "../ui/Nav";
import { Navigate, useParams } from "react-router-dom";
const API_URL = "http://www.omdbapi.com/?apikey=cca6a59";
function Movies() {
const [movies, setMovies] = useState([]);
const params = useParams();
const title = params.id;
const [loading, setLoading] = useState(true);
async function onSearch() {
await fetchMovies();
Navigate(`/moviecard/${movies}`);
fetchMovies(movies)
}
async function fetchMovies(title) {
const { data } = await axios.get(`${API_URL}&s=${title}`);
setMovies(data.Search);
setLoading(false);
}
useEffect(() => {
fetchMovies(title);
}, [title]);
return (
<>
<Nav />
<div className="movie__row">
<div className="movie__wrapper">
{loading
? new Array(8).fill(0).map((_, index) => (
<div className="movie" key={index}>
<div className="movie__img--skeleton">
<div className="movie__title--skeleton">
<div className="movie__year--skeleton"></div>
</div>
</div>
</div>
))
: movies.map((movie) => (
<div className="movie" key={movie.id}>
<div className="movie__img">
<img src={`${movie.Poster}`} alt="poster" />
<div className="movie__content">
<h1>{movie.Title}</h1>
<h1>{movie.Year}</h1>
<p onClick={() => onSearch()}>SEE MORE</p>
</div>
</div>
</div>
))}
</div>
</div>
</>
);
}
export default Movies;
This is the code after the user selects "SEE MORE" after selecting the specific movie:
import { useParams } from "react-router-dom";
import Nav from "../ui/Nav";
import { useEffect, useState } from "react";
import axios from "axios";
const API_URL = "http://www.omdbapi.com/?apikey=cca6a59";
function Moviecard() {
const params = useParams();
const imdbID = params.id;
const [desc, setDesc] = useState([]);
const [loading, setLoading] = useState(true);
async function fecthDesc() {
const { data } = await axios.get(`${API_URL}&i=${imdbID}`);
setDesc(data.Search);
setLoading(false);
}
useEffect(() => {
fecthDesc();
}, []);
return (
<>
<Nav />
{loading
? new Array(1).fill(0).map((_, movie) => (
<div className="movie__img--wrapper">
<h1>${movie.Title}</h1>
<img src={`${movie.Poster}`} alt="" />
</div>
))
: desc.map((movie) => (
<div className="movie__info--wrapper" key={imdbID}>
<h3>
<span className="red">Released: </span>${movie.Released}
</h3>
<h3>
<span className="red">Actors: </span>${movie.Actors}
</h3>
<h3>
<span className="red">Genre: </span>${movie.Genre}
</h3>
<h3>
<span className="red">Director: </span>${movie.Director}
</h3>
<h3>
<span className="red">Writer: </span>${movie.Writer}
</h3>
<h3>
<span className="red">Language: </span>${movie.Language}
</h3>
<h3>
<span className="red">Plot: </span>${movie.Plot}
</h3>
</div>
))}
</>
);
}
export default Moviecard;
I’m sure it is something small that I’m just forgetting but I don’t know how to attack this problem.
2
Answers
The code is directly calling, e.g invoking, the
Navigate
component instead of passing it as JSX to be rendered by React. This isn’t what you want to do here though.useNavigate
hook from React-Router-DOM and issue an imperative navigation action.fetchMovies
call from the callback, the movies were already fetched when the component mounted.Example:
async function onSearch() {
await fetchMovies();
This fetchMovies() looks suspicious, you didn`t provide parameter. It is intended?