Build Youtube in React 32: dynamic watch component
We’re done with our
Home feed, but we still need to make our
Watch component dynamic. In this tutorial, we will start fetching the data we need for it.
2 Making our video viewing component dynamic
2.1. Adding links to video thumbnails
We can scroll through our
Home feed, but when we click a video thumbnail nothing happens. We want the user to be redirected to our
This can be accomplished by using the
react-router Link component.
Let’s wrap the entire content inside
src/components/VideoPreview/VideoPreview.js) inside a
VideoPreview component now expects two new
prop is the absolute path to which the user should be redirected to. For example, if we want to get redirected to
pathname must be set to ‘
search prop is the query string that we want to append to the address, so if we want to add
?id=1234 as query parameters to our
URL, we need to set the
search prop to
2.2. Updating video grids
VideoGrid component inside
src/components/VideoGrid is responsible for creating video preview elements. Therefore, we need the component to pass a
pathname and a
search prop to
2.3. Verifying that the links in Home feed work
Go to the
Home feed, click on one video aaaaaand 😡
Nothing happens. Now why is that? Well the reason is
When we included Redux, we also gave it control over when our component re renders. The issue we ran into is called update blocking.You can read more about it in the official react-router repository.
Redux is taking control of our component and does not re render it when the
URL changes. A component is re rendered when at least one of its properties changes. So if we make the
URL / location a property of our App component then our component should be re rendered as soon as the
URL is updated.
The only thing we need to do is to wrap our
App component inside the
withRouter higher order component. The
withRouter helper basically inserts the current
URL as a prop inside our component. It is accessible via
this.props.location. So if our
URL changes, our
App component re renders and we get redirected.
Change the default export in your
App.js file like so.
Once you click a video thumbnail, you should now be redirected to
This is not something I came up with, but this is how
Youtube's URL structure works
2.4. Intermediary Result
Click on the image to see it in high resolution.
It’s looking a little bit empty around here because we only have placeholders in here. We need to change that. But first, let’s think about what we need to do.
We need to display the video’s metadata (likes, dislikes) along with its title in here. Note that we will also need the text that goes into the video description. When we loaded information on trending videos in the
Home feed, we did not load the video description because it was not needed. Loading the video description for multiple videos also comes with quite a high latency. Therefore, it makes sense to load the
description / the info box text only when the user actually watches the video.
2.5. Scrolling to the top with react-router
Now you might have noticed an issue here. If scroll down the
Home feed and then click the video thumbnail, you end up in the
However, you might not have ended up at the top of the page. That is because we just go to another page, but keep our scroll position.
We don’t want to have such a behaviour. When the user navigates to another page, he/she should always end up at the top of the page.
Fortunately, this is a rather small issue that can be fixed pretty quickly. We will just create a component that always scrolls to the top when the
- Create a new directory inside
src/componentsand call it
- Add a
ScrollToTop.jsfile inside the directory you just created.
componentDidUpdate lifecycle method, we check if the location has changed. If yes, then we use the
window.scrollTo function to scroll to the very top of the page.
In terms of rendering, the
ScrollToTop component will just return all its children. We use the
withRouter helper so that we have access to the current location.
AppLayout component? In here, we make sure that we always have a top bar in our app. We can just wrap all that in the
ScrollToTop component and we’re good.
So head over to your
2.6. Extracting search parameters from URL in React
Ok, back to the topic and back to the
Watch component. Once we end up inside our
Watch component, we will reach out to Youtube’s videos endpoint and fetch information on a particular video. Remember that we are adding the
video id to the query string of our
URL. So if our URL is
/watch?v=abcdef, then we need to fetch detailed information on the video with the id
Let’s add a new function inside our
Watch component that extracts the video id.
Pretty easy isn’t it 🤓
2.7. Fetching video details from Youtube endpoint
Before we start creating our action creators, we first need to understand to which endpoint we want to reach out.
The goal is to load very detailed information on a video. Wee need the video title, the amount of likes / dislikes and its description.
It turns out that we need to reach out to the Videos endpoint again which we used to fetch trending videos.
However, this time around, we just want to fetch information on one particular video identified by a
Please have a look at the API explorer to see what I mean.
Here’s an example request to get more information for the video identified by id
That’s an easy one. Head over to the
src/store/api/youtube-api file and add the following code:
Note that we are making use of the
fields parameter to not load too much information. Like so, we get a faster response.
2.8. Fetch watch details action creator
To fetch more detailed information on a video associated with a particular id, we need to create actions first.
We will call this action
- Create a new file inside
src/store/actionsand call it
We make use of our action creator methods to speed things up a little bit.
2.9. Video details watcher saga
To reach out to the endpoint, we need to create a watcher saga that forks a
worker saga when it detects the
Let’s create a new file to not clutter our code
- Create a new file inside
src/store/sagasand call it
We start out with the easy part and create the
watcher saga first.
We listen to the
WATCH_DETAILS_REQUEST action type and extract the
videoId parameter from it. After that we
worker saga and pass along the
2.10. Video details worker saga
One hint upfront: we need to reach out to multiple endpoints to fetch all the information we need in our
Watch component. This means that we will need to make multiple requests concurrently and chain them together later on. We will do this step by step and start with fetching detailed information on a particular video.
Right now, we’re just firing one request. Therefore the approach with the requests array seems overkill. We will improve the worker saga incrementally and add more requests to it later on.
We use the
all effect whose semantics is comparable to
Promise.all) to perform all requests in the requests array. Once we are done, we dispatch the
WATCH_DETAILS_SUCCESS action. In case the request is not successful, we dispatch the
2.11. Wiring up watch details watcher saga to root saga
To actually make use of our logic, we need to include our
watcher saga into the
Head over to your
src/store/sagas/index.js file and plug our new
watcher saga in.
3 Wrap Up
We’re getting there.
In the next tutorial, we will work on the
reducer and will gradually fetch more data from the
Thanks for reading, you can find the project’s code on Github.Follow @productioncoder
Please follow me on Twitter @productioncoder to stay up-to-date. I’m happy to receive feedback of any kind.
If you are interested in more high-quality production-ready content, please enter your email below.