Reputation: 401
I have a Next.js app that plays random YouTube videos. My state for the app looks something like this (in a Redux store):
const state = {
entities: {
videos: {
'vidId1': {
id: 'vidId1',
title: 'Video 1'
},
'vidId2': {
id: 'vidId2',
title: 'Video 2'
},
'vidId3': {
id: 'vidId3',
title: 'Video 3'
}
}
},
uncategorized: {
isFetching: false,
hasNextPage: false,
nextIndex: 0,
items: [
'vidId1',
'vidId2',
'vidId3'
]
}
};
I then have my home page that looks something like the following:
// index.js
const Index = () => {
return (
<div>
<h1>Home Page</h1>
<RandomVideoButton />
</div>
);
};
The <RandomVideoButton />
links to /random
. This page just gets the next video ID from the state and redirects to /videos?id={id}
. It looks something like this:
// random.js
const RandomVideo = () => {
// Get next video ID
const nextVideoId = useSelector(state => state.uncategorized.items[state.uncategorized.nextIndex]);
// Redirect to next video
const router = useRouter();
router.push({
pathname: '/videos',
query: { id: nextVideoId }
});
return (
<div>Loading video...</div>
);
};
Once I'm on /videos?id={id}
, that page will load the video from state.entities.videos
and it will then update state.uncategorized.nextIdnex
. This is where the problem occurs. When I dispatch the action to update the next video index in the state, I get stuck in an infinite re-render loop. This is what watch.js
looks like:
const WatchVideo = () => {
// Get video ID from URL query
const router = useRouter();
const videoId = router.query.id;
// Get video
const { video, activeVideos } = useSelector(state => state.entities.videos[videoId]);
// Update video index
const dispatch = useDispatch();
dispatch({ type: 'INCREMENT_NEXT_INDEX' });
return (
<div className="col-12 col-lg-8 col-xl-9">
{video &&
<main>
<div className="embed-responsive embed-responsive-16by9">
<iframe id="player" src={'https://www.youtube-nocookie.com/embed/' + video.id}></iframe>
</div>
<h1>{video.title}</h1>
</main>
}
</div>
);
};
My problem is I'm not sure how to prevent this from happening while still being able to update next video index in the state.
Upvotes: 0
Views: 1456
Reputation: 1086
you should use dispatch/routing inside react useEffect hook. and you can use the videoId as a useEffect dependency.
Upvotes: 1