Youtube in React 44: kicking off a search from the top nav bar
We’re finally about to start building out our
Hold on a second. The
UI for the search results looks almost identical to what we have in our
To prevent code duplication, let’s create a new component for this. This will not only make our code cleaner but will also save us work when we create the markup for our
2 Video list component
2.1. Creating a video list component with infinite scroll
This component will be a presentational component, so let’s put it into
- Create a new directory inside
src/componentsand call it
- Add a
VideoList.scssfile inside the directory you just created
Now we can basically copy and paste the content of the markup from our
Trending component in here.
2.2. Video List makeup
Now before we start with all the markup, remember that we basically already have the styling for our
VideoList component. We want it to show a list of
video previews just like we have it in our
Trending component. So just go ahead and copy the
Trending.scss into the
VideoList.scss file. Note that we renamed the
.trending class to
.video-list so that it is generic.
2.3. Video list component markup
Great, now that we have the cosmetics done, we can finally move on to the
function. In fact, we can more or less copy the contents of our
function in here and make a few minor adjustments. I won’t go into detail about the markup here because we already covered this when we did the
Basically, we expect the parent component to pass an array of
videos. It also expects to receive a
function that is called when the user scrolled to the bottom. In addition, the component would like to receive a
boolean flag that indicates whether the
spinner should be shown or not.
Now we still need to implement the
getVideoPreviews function which returns us an array of
video preview components.
2.4. Generating video previews
Just put the following function under you render function.
You might be wondering what the hell we are doing at the beginning of this
function. We’re just making sure that the
videos we get passed already have a
description. So suppose you come from the
Home feed and you click
Trending on the left side bar. We already loaded some of the most popular videos – but without
Trending component would display our video previews without
description first. Once our network request finishes, our
Trending component re-renders and shows the video previews with
This looks super strange for the user because he/she only sees the video thumbnail and its title and suddenly a
description pops up. We don’t want to have this behaviour. The
VideoList component should only show the video previews once the video descriptions are there. Since we load multiple videos in one blow, it is sufficient to check if the first video has a
description. If yes, we can be reasonable certain that the other videos have a
description as well.
In this case we map over the videos and generate
VideoPreview elements from them. Once clicked, the user should be redirected to the
Watch component. That’s why we pass the pathname and
2.5. Updating Trending component
Now that we outsourced the markup and the
CSS to a separate component, we can clean the
Trending component up (
First of all, we don’t need the
Trending.scss file anymore. So please go ahead and delete it and delete the
import statement in
Trending.js as well.
We can also update
Oh wow, that looks much easier. The cool thing is that we can recycle this approach in our
You can also delete the
getVideoPreview function inside
Trending. We already moved this functionality into our
VideoList component. Thanks to that, we can directly pass
this.props.videos into the
3 Searching for videos
3.1. How search in Youtube works
Before we start to create our search component, let’s quickly review how searching in the original
Youtube app works. Head over to youtube.com and type something into the top search bar and hit enter.
Have a look at the
URL. If you search for “
URL looks like this:
So we get redirected to a
/results page and have a new query parameter called
We will adapt this concept as well, so that our
URLs are compatible with those of
3.2. Creating the files
Nice, now that we have the network logic in place, we can now start to create a new component.
Let’s give it a speaking name and call it
Search. Since it will reach out to the network, it can be considered a
stateful component. Therefore, we put our new component into
- Create a new directory called
Searchand put it into
- Add a
Search.scssfile into the directory you just created
Let’s create a
skeleton for our component first.
You probably already guessed that we will use our
VideoList component in our
function. So the markup in the
function will be super easy. But first, we need to add all the network and routing logic.
3.3. Adding state to HeaderNav bar
Now that we know how the search is supposed to work, we need to make some changes in our top bar. The idea is that the user types in a
search query and hits enter. Then the user gets redirected to our
Search component with the respective results. So please head over to our
We will store the current
string the user entered into our
text field in the local state of our component. To do so, let’s add a constructor to our
Also note that we are using the
withRouter helper so that we have access to location in our
props. We will need this when we redirect the user.
3.4. Event handlers for header navigation form
Great, let’s add two event handlers that we will need when the user types something in and when the form is submitted. Add the following code underneath the
We would like to call the
function whenever the user performs a keystroke. Whenever this happens, we update the query variable in our component’s local state.
Once the user hits enter or presses the submit button, we get the search query from our local state. That’s why we have been saving it in the first place. We call the
function so that special characters such as
'&' and so on are escaped. The search query will be part of the
URL after all.
After that we redirect the user to
/results and add the
3.5. Updating Header Search markup
Now that we have the redirection and form handling logic, we can actually use it in our markup.
Menu.Item element with the
.search-input like so:
We wired up our
onSubmit function with the
form element. So every time the user hits enter or hits the form submit
function will be called.
In addition, we attach the
onInputChange function to our input element. So every time the user makes a keystroke, we update our local state. The
input's text will be determined of what we have saved in our state. That’s why we set the value
3.6. Adding search component to our router
We haven’t registered the
/results route yet. But no worries, that’s super easy.
Go to your
App.js file and add a new
Note that we are using the exact same approach that we used with the
Watch component to enforce a re
render when the
search parameters change. To do this, we simply pass the
location.key element as
props to our component. You can read a more detailed explanation about this approach in tutorial 36.
4 Wrap up
Ok, so let’s test this out. Head over to your
Home feed and enter something into the text field in the top navigation bar and hit enter.
You should be redirected to the Search component.
Click on the image to see it in high resolution.
All right, this seems to work. In the next tutorial, we will fill our search component with life.
As always, thanks for reading. You can find all the code in our Github repository.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.