I have a component where I use useEffect
and inside call a function fetchLatest()
. fetchLatest()
is an action that makes a network request to get all movies that have been released during the current year. I am using Redux and in my store I have a state.movies.latest
and each time I start the app for the first time the latest row of movies is accurate with no duplicated data. When I render a different component and go back to my home component where I do fetchLatest
I then get duplicated data.
I figured out that my problem is because in my reducers I return something like...
return {
...state,
latest: [...state, ...payload]
}
where payload
is an array of objects (movies).
So I changed my reducers to...
return {
...state,
latest: [...payload]
}
It works now and I don't get duplicated data but my concern is that I am not doing or understand this correctly. If I were to use useEffect and have my fetchLatest function in my useEffect hook and pass it as a dependency to my understanding my function fetchLatest
will be recreated after every render cycle as a brand new object. Being that I already have in the store my latest
array of movies I do not want to re-render a brand new object each time causing to add to my store in my state.movies.latest
duplicated data. I at least believe this is what it is doing.
I decided that maybe I should be using useCallback
to ensure that this brand new object of fetchLatest
is not created unless its dependencies change.
So what I am not sure about is maybe I can have my updated reducer as I have it now and also useCallback to ensure no infinite loops are running for recreating my fetchLatest function each time as a new object when I re-build that component?
Also, I might not understand actually what useCallback does because I tried before using a useCallback and having my reducer as I originally had it and to my understanding if nothing changed then why is it that my fetchLatest runs when I rebuild the component. I only want my latest movies which I already have in the store when I first mount my component
my code for this component looks like this
const Latest = ({ fetchLatest, latest }) => {
useEffect(() => {
fetchLatest();
}, [fetchLatest]);
return (
<div className='genre-temp'>
<h3 className='text-light'>Latest</h3>
<div className='movies-container d-flex'>
{latest.map((movie) => (
<Movie
key={movie.id}
movieId={movie.id}
image={movie.image}
title={movie.title}
description={movie.description}
/>
))}
</div>
</div>
);
};
and what I had tried to do initially was add this useCallback and call handleFetching in my useEffect and pass it in as a dependency.
const handleFetching = useCallback(() => {
fetchLatest()
}, []);
However, useCallback in conjunction with useEffect while still having my reducer as such...
return {
...state,
latest: [...state, ...payload]
}
still would run each time the component rebuilt.