Build Youtube in React 40: displaying comments
1 Overview
Let’s continue where we left off and finish off the comments.
2 Displaying comments
2.1. Comments selector
We only need a way to pull in the comments for a specific video into our WatchContent
component. We will use a selector
for that. So head over to your src/store/reducer/comments.js
file and add the following code.
First, we create a helper function
. This helper function returns the comment ids
for a particular video if any. We use our little helper function later in our selector.
We iterate over all comment ids
and return the corresponding comment object
. The selector
returns an array of comment
objects that belong to a specific video.
2.2. Pulling in comments into WatchContent
Let’s use our selector to connect our WatchContent
component with our Redux
state.
We update our mapStateToProps
function
to pull comments of a particular video into our local state. The selector
we just created is just perfect for this. Next, we pass the array of comments objects down to the Comments
component. This is one of the components we need to update next.
But wait. There’s just one more thing. We currently pass a hard-coded number in the amountComments
prop. We should change that.
2.3. Selector for total amount of comments
Now here’s a little caveat. When we fetch a comment thread, the pageInfo.totalResults
field does not hold the total amount of comments
for a specific video. It just tells us the total amount of comment threads we just fetched in one blow. The information on how many comments a video has is stored in the video.statistics
object.
You can also see this in the API explorer.
So I suggest, we create a selector for this. We will create it in the videos
reducer, because that’s where our entire video logic lives.
Put the following code into src/store/reducers/videos.js
We can just recycle our getVideoById
selector we already have and return the video’s overall amount of comments.
2.4. Wiring up the total amount of video selector
Now that we have our new selector
, we can make use of it in the WatchContent
component.
We add a new field called amountComments
in our mapStateToProps
function. All we need to do is to pass the current video id
. Now instead of passing down a hard-coded number down to our Comments
component, we can now pass the correct number.
2.5. Making our Comments component dynamic
Currently we only have hard-coded elements in our Comments
component. Dynamically creating the comments
is super easy.
First of all, we check whether we get a comments
props. If not, we just return
an empty <div>
. Once we know that we have some comments, we iterate over them and create a comment
component for each element. After that, all the comments are rendered.
Now the only thing that’s left to do is to update the Comment
(note: singular) component. That’s an easy one as well. We already have the markup ready. We just need to display the actual data.
2.6. Intermediary result
Let’s try our magic out.
You should see something like this. Click on the image to see it in high resolution.

Ok, that’s kinda cool. But wait, we only show a few comments. It would be great if we could load more comments once we hit the end of the page. Fortunately implementing this is pretty easy. In fact, we already did it in our Home
feed. We will need a next page token
for this.
Well, we already have that, what a coincidence 😁. Having a well structured Redux
state pays off.
2.7. Fetching more comments action creator
Once we hit the end of the page, we want to reach out to the Youtube
endpoint and load more comments. We will need an action for that.
- Create a new file inside
src/store/actions
and call itcomment.js
We will reach out to the /commentThread
endpoint again. So here’s our action creator.
We expect two parameters in our request. The first one is the video id
for which we want to fetch more comments. The second parameter is the next page token
so we can load additional comments and not just the first 20
or so.
2.8. Fetching comments sagas
Fortunately, we have already a created a function
that reaches out to the /commentThread
endpoint. We can just recycle it. To actually make the network request, we need a watcher
and a worker saga
.
Let’s put these sagas into a separate file to keep our project clean.
- Create a new file inside
src/store/sagas
and call itcomment.js
In our watchCommentThread
saga, we listen to the COMMENT_THREAD_REQUEST
action. Once such an action is dispatched, we extract the video id
and the next page token
from its payload and fork
a worker saga
. This worker saga
is supposed to do the actual work.
Our worker saga
uses our buildCommentThreadRequest
function to construct the appropriate request. We then use the fetchEntity
function to reach out to the network.
There’s just one more thing to do. We need to plug our new watcher saga
into our root saga
inside src/store/sagas/index.js.
2.9. Comment thread reducer
Now we only need to incorporate the new data into our state once we get it. You might be surprised how easy that is.
Remember that we’ve already done the hard work when we deal with the WATCH_DETAILS_SUCCESS
action. We can just recycle our reduceCommentThread
function
. What a lucky coincidence, … not 😁
Dealing with our action just boils down to adding a new case
statement in our reducer
.
2.10. Next page token selector
You already noticed that we can pass a next page token
as a payload
to our action. To really implement infinite scroll, our components needs to dispatch the COMMENT_THREAD_REQUEST
action and pass along the next page token
. We should create a selector
for this to not couple our components with our Redux
state.
We create a little helper function called getComment
. getComment will make use of our getSearchParam function to extract the video id
from the current URL
. It will then search for the corresponding object inside our state.comments.byVideo
object. Once we have that, we return the object’s next page token
if it is available. Pretty straight forward.
2.11. Infinite scroll for comments
Our Watch
component is currently responsible for fetching all the data as as far as watching a video
is concerned. So we will wire up our next page token selector
with our Watch
component and fire the request when needed.
First, we pull in the comment next page token
into our component’s state. We do this by making use of our getCommentNextPageToken
function inside mapStateToProps
.
Oh, and we also need to wire up the comment thread request action creator to our local state. Let’s do this in our mapDispatchToProps
function.
The fetchMoreComments
function
makes dispatches the COMMENT_THREAD_REQUEST
action when we call it. This is only done if we have a next page token
available. Otherwise we would just fetch the first n
comments of a video again.
Finally, we pass the fetchMoreComments
function to our WatchContent
component. WatchContent
will call this function
whenever the user scrolls to the bottom. When this happens, our Watch
component makes sure we fetch new comments which are later displayed..
Note that we also pass down the nextPageToken
to our WatchContent
. You will later see why
2.12. Infinite scroll in WatchContent
We make use of our InfiniteScroll
component we already developed when we did the Home feed
.
We recycle our InfiniteScroll
component from our Home
feed and pass it the function
it should call when the bottom is reached. We also pass a boolean
flag that indicates whether a circular loader should be displayed at the bottom of the screen or not.
The shouldShowLoader
function
returns true
if we have a next page token
. If not, it returns false
. Now technically speaking we don’t really need this !!
operation because if nextPageToken
contains something, it will be considered true
anyway. But I just did it to make clear, that we pass a boolean
here. So we only need to know whether we have a next page token
, not how that token looks like.
3 Wrap Up
Yes, yes yes. We’re done with our Watch
component.
Look at this, isn’t that nice. We now have infinite scroll in here.
Click on the image to see it in high resolution.

You can find all the source code on Github.
Now we only have two things left to finish this tutorial series off.
Follow @productioncoderPlease 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.
Recent Comments