When I try to show the title of a movie (line 8 of App.js) I get the error "Uncaught TypeError: movies[0] is undefined". If I do a log of the variable "movies" after line 5 the console makes two logs: Frist, logs movies as an empty array and then logs movies as an array with all the content, like I want.
The weird thing is that if I delete the line 8 {movies[0].title}
and save the error dissapears as normal, but then if I add it again and save the movie title renders on screen like I'm trying to do.
App.js:
import './App.css';
import useApi from './useApi';
function App() {
const movies = useApi();
return (
<div className="App">
{movies[0].title}
</div>
);
}
export default App;
My useApi returns an array with a list of movies:
import axios from 'axios';
import { useState, useEffect } from 'react';
const useApi = () => {
const [movies, setMovies] = useState([]);
const getData = async () => {
try {
const res = await axios(url);
setMovies(res.data.results);
} catch (error) {
return [];
}
}
useEffect(() => {
getData();
}, [])
return movies;
}
export default useApi;
Knowing that if I print movies it logs an empty array but then it prints it normal like I said, i guess I'm having a problem with asynchrony but I can't figure out what. And the fact that it works when removing and readding line 8 makes me more confused.
CodePudding user response:
You may want to use the notion of conditional rendering. Something like this may work:
import './App.css';
import useApi from './useApi';
function App() {
const movies = useApi();
if (movies.length) { // conditionally render when the movie list is not empty
return (
<div className="App">
{movies[0].title}
</div>
);
}
return <div>Loading...</div>
}
export default App;
CodePudding user response:
Because your getData() function render two times in useEffects hook. You need to check if(movies.length>0) and after that type return!