Youtube in React 45: displaying search results
Almost done, we already have the network logic for our
search component in place.
We just need to make use of it to achieve our goal.
So let’s get it over with 🤓.
2 Finishing search component
2.1. Adding state to search components
Before we create the markup, let’s first
connect our component to our
Redux state. We can just make use of the
selectors we created previously. Go ahead and add a
mapStateToProps function pulls in three things from our global
booleanflag whether we already loaded the client library
searchresults from our network request
next page tokento fetch more search results if needed
mapDispatchToProps function we bind our
forVideos.request action creator to
2.2. Getting the search query, the user entered
Before we can do the actual search, we first need to get the entered search query. As discussed in section 4.1., we need extract the
search_query query parameter from our
URL. We already did something similar in our
Watch component and can just recycle the logic we used there.
2.3. Performing the search network request
Finally, we can create the
function that will actually perform the network request.
We will call this
function in our lifecycle function
When the component was mounted, we check if we even have the
search_query parameter in our
URL. If not, then we redirect to our
Home feed because without the
search query, we cannot do anything.
However, if the
search_query query parameter exists, we call our
function to perform the search.
Now suppose someone navigates to the search component directly by pasting a
/results?search_query=surfing URL in their browser. In this case, we probably haven’t loaded the Youtube client library yet.
Therefore we need to wait for the client library to load. Once it is loaded, we can perform the request. In our
componentDidUpdate function we check if the
youtubeApiLoaded prop has changed. We do that to not perform the search request twice. This property only changes once during the lifecycle of our application because we only load the client library one time.
2.4. Verifying that our search magic works
Let’s do a quick check to make sure that everything is working as expected. Enter some search term into the top bar and hit enter. Please check the
Redux devtools extension afterwards.
Redux dev tools should indicate that we indeed performed a network request.
Click on the image to see it in high resolution.
2.5. Search render function with infinite scroll
At the beginning of this section I already mentioned that we will use the
VideoList component. Well, now it’s about time, isn’t it? The only thing we still need is a
callback that will fetch more search results when the user scrolled to the bottom of the page.
So here we go.
So we finally got search working:
2.6. Fixing search flickering issues
There’s something interesting going on here. Try it out.
- First go to the
Home feedand type an arbitrary search query in. You’ll then see the results.
- Now go back to the
Home feedby clicking on the
- Type something else into the search box
Did you see it? It’s sort of flickering. Why is that? Well, remember that we save the previous in
state.search. When the user gets redirected to the
Search component, we do two things.
First of all, we will reach out to the
Youtube endpoint and fetch some search results. Bear in mind that this can take a few hundred milliseconds. This is enough time for
render our component. But it is
rendering it with the previous search results! And then shortly after, we get the results from our current
search and re render everything. This is kind of confusing to the user.
But there is a simple fix. When we
SEARCH_FOR_VIDOES_REQUEST action, we can just delete the previous search result.
However, we only want to delete the previous search if we are not fetching more search results for the previous query. So if our
infinite scroll dispatches this
action, we definitely want to keep our results. We can immediately tell that by checking if we got a
next page token. If we didn’t get a
next page token, then we are performing a new search.
Head over to your
src/store/reducers/search.js file and add a new
case statement in the
reducer receives the
SEARCH_FOR_VIDEOS_REQUEST action, it will delete the previous search
results. Note that this is before we are even attempting to
render the search results because our
HeaderNav component first dispatches this action and then redirects to the
2.7. One more thing…
My friends, upon finishing the entire series, I started to feel that the video in the
Watch component is a little big too big. This doesn’t really have anything to do with
Search, but I just wanted to get it over with before the end of this series.
I’ve already expressed my enthusiasm towards
CSS grid. Here’s yet another reason.
Head over to the
src/containers/Watch/Watch.scss file and add update two lines
We just updated the structure of our columns. The
minmax basically says, I want this column to at least have a
minimum width of
0 and a
maximum width of
So our column will expand as much as it can, but only to a
maximum width of
1280px? Well, because like so our app looks similar to the original
Youtube app. Now of course you might argue what happens when you have a screen with a super high resolution.
Apparently the content does not expand and still has a width of
1280px. I’ve tested it with the
Chrome Dev tools.
We also added a media query to our
CSS class so that we have a
24px left and right padding in our
Watch component in case we are on a smaller screen.
Click on the images to see them in high resolution.
1) 2560px x 1440px (1440p display)
3840px x 2160px (4K display)
So it seems that as of this writing, the original
Youtube app cannot cope with these resolutions that well. If it’s good enough for them, it’s good enough for us as well.
Here’s how our
Watch component looks right now (
3 Wrap Up
Oh wow, it’s working. Just type something in the search box and see for yourself.
Watch component even looks pretty much like in the original app. 👍
You can find entire code on Github.
Thanks for reading. This will also be the last tutorial in this series.
So we are finally done 🎉🎉🎉
Wow, that was a hell of a tutorial, wasn’t it 😁
You really gotta be a maniac if you are still sticking around.
Anyway my friends, thank you very much for all the support.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.