Reputation: 11
I am building a movie app in React to practice.
In the homepage there is a big banner with movie poster and information about movies, content of this banner is changing every 5 seconds. I created this function for this:
const [movie, setMovie] = useState(''); //const movie returns object of one random movie
useEffect(() => {
async function fetchData() {
const request = await axios.get(requests.fetchNetflixOriginals);
setMovie(
request.data.results[
Math.floor(Math.random() * request.data.results.length)
]
);
}
const interval = setInterval(() => {
fetchData();
}, 5000)
return () => clearInterval(interval)
}, [movie]);
This solution has a problem: there is a 5sec delay when I run this app for the first time (caused by setInterval).
So my question is, if there is any solution to get the same behaviour, just without the delay at the start?
I tried a lot of different solutions including defining new states, but all of them causes bugs or infinite loop.
Thanks!
Upvotes: 0
Views: 968
Reputation: 1
I fixed the issue, after adding another useEffect hook. But i am not sure if it will call some other issue.
useEffect(() => {
fetchData()
})
Upvotes: 0
Reputation: 11
Yes, I have already tried exactly this solution with invoking function firstly and then setting an interval. But the result is that banner starts to have crazy behaviour. It changes literally 10x in a single second endlessly.
I attach a whole updated component code to be sure I didn't miss something to send:
const Banner = () => {
const [movie, setMovie] = useState({});
useEffect(() => {
async function fetchData() {
const request = await axios.get(requests.fetchNetflixOriginals);
setMovie(
request.data.results[
Math.floor(Math.random() * request.data.results.length)
]
);
}
fetchData();
const interval = setInterval(fetchData, 5000)
return () => {
clearInterval(interval)
}
}, [movie]);
function truncate(str, n) {
return str?.length > n ? str.substr(0, n - 1) + '...' : str;
}
return (
<header
className='banner'
style={{
backgroundSize: 'cover',
backgroundImage: `url(https://image.tmdb.org/t/p/original/${movie?.backdrop_path})`,
backgroundPosition: 'center center',
}}
>
<div className='banner__contents'>
<h1 className='banner__title'>
{movie?.title || movie?.name || movie?.original_name}
</h1>
<div className='banner__buttons'>
<button className='banner__button'>Play</button>
<button className='banner__button'>My List</button>
</div>
<h1 className='banner__description'>
{truncate(movie?.overview, 120)}
</h1>
</div>
<div className='banner--fadeBottom'></div>
</header>
);
};
Any ideas what should caused it/how to prevent from this behaviour?
Upvotes: 0
Reputation: 371233
Just call fetchData
when defining the interval?
useEffect(() => {
async function fetchData() {
const request = await axios.get(requests.fetchNetflixOriginals);
setMovie(
request.data.results[
Math.floor(Math.random() * request.data.results.length)
]
);
}
fetchData();
const interval = setInterval(fetchData, 5000)
return () => clearInterval(interval)
}, [movie]);
Upvotes: 3