I have two buttons, the movies
and tvshows
button. When I click on either I change the option
to the opposite one as shown on the handleMovieClick
and handleTVShowsClick
methods. Movies and TVshows may have the same id, that is why the option
is important for fetching.
I am printing to the console.
(1) array
of movie/tv ids
(2) the option
selected
(3) each individual object fetched based on the id
and option
When I use the value
to calculate the array
of movie ids available the first time, I first get an empty array and then the expected result. That is the array
of movie ids, option is movie and each individual promise objects is fulfilled.
Here's the kicker, when I click on the tvshows
button, I am getting the following two things consoled.
(1) same movie array
of ids not updated, option changes to tv
, however I get a bunch of promises with "status_message: "The resource you requested could not be found" because I am basically trying to retrieve promises with movie ids, but tvshow option.
Then,
(2) Then the result is changed and I everything as expected. That is option stays the same, changed in above step, the array
gets updated, and the individual promise objects are all fulfilled.
What is happening?
I get that it is happening because of the code in my JSX where I am making use of the array
ids. I think I need to only call the array.map()
part after the useEffect has run and the so array is updated but how to do this and why is useEffect not running the first time?
Here is the code.
const Results = () => {
const options = ['movie', 'tv'];
const { value } = useParams(); // from router
const [ page, setPage ] = useState(1);
const [ option, setOption ] = useState(options[0]);
const [ array, setArray ] = useState([]);
const handleMovieClick = () => {setOption('movie')}
const handleTVShowClick = () => {setOption('tv')}
useEffect(() => {
console.log('HERE');
fetchArrayByPage(value, page, option).then(res => setArray(res));
}, [value, page, option])
console.log(array);
console.log(option);
return (
<div className="results-container">
<div>
<ul className='categories'>
<button onClick={handleMovieClick}>Movies<span>{0}</span></button>
<button onClick={handleTVShowClick}>TV Shows<span>{0}</span></button>
</ul>
</div>
{
<div>
<div className='results-list'>
{array.map((arr, index) => {
console.log(fetchID(arr, option));
return <Card key={index} id={arr} option={option}></Card>})}
</div>
<div className='pages'>
</div>
</div>
}
</div>
);
}
useEffect
's callback is fired after the render and fetchArrayByPage
seems to be async. So clicking on "TV shows" results in:
option
is changed to "tv" (array
stays the same)console.log(array); console.log(option);
option
and old array
console.log('HERE'); fetchArrayByPage(...)
setArray(res)
option
and new array
You should call fetchArrayByPage
from your handle*Click
handlers:
const handleTVShowClick = () => {
fetchArrayByPage(value, page, "tv").then(res => {
setOption('tv');
setArray(res);
});
}