Build Youtube in React 33: reducer for watch video component
Let’s continue where we left off and start with creating the
reducer for our
2 Adding watch details reducer
2.1. Let’s talk about state
It is important to understand where we store the more detailed information on the video we are about to fetch. It has to live somewhere in our global
When we have more information on a video, we will just add / update an entry in our
videos.byId “dictionary”. So the new state might look like this:
Have a look at line
10. We simple replace or update the video associated with a particular
id. Now we also have the description for the video associated with id
Now that we are clear on how to store the data, we also know that we must update our videos
2.2. Endpoint response format
Let’s first talk about how the endpoint’s answer is structured. Since we are using the
all effect, we expect to get an array of responses back. Right now we only perform one request, so we expect the array to only contain one element.
A typical response for the call we are about to make looks like this.
Remember that when doing a request with
redux saga, we also get a bunch of other stuff in our response we don’t really need. Generally, a response consists of three parts.
The result contains the response in the form of a
JSON object. This is what we will be working with. The entire response string is stored inside
body. We also get information on the
Now we don’t care about the
headers and the
body for now and will just be working with the
I’m just bringing this up so that the
reducer is easier to understand.
2.3. Reacting to watch details action in video reducer
We add a new
case statement to our
switch and now react to the
Let’s have a look at the
reduceWatchDetails function which does the actual work. We will first look at a quick and dirty solution and then do it properly.
We know that the
items array in the responses array will contain the details about a particular video.
So we could simply get the first element in the responses array. That’s the response we’re looking for. We also know that the
items array of the response (as shown above) will just contain one element because the
video id is unique. So we could simply take the first element in the items array and insert that into our videos.byId object.
This sort of works, but that’s not the quality we’re striving for. This parsing mechanism is very fragile. If we change the action later on and the first response is no longer the response with the
video details, our entire
reducer crashes and burns.
So let’s do this properly.
2.4. Robust watch details reducer
Instead of just taking the first response and hard-code an index, we just use the Array.prototype.find function.
The find function will return the first item that matches the condition we specify. We are searching for a response of kind
Youtube returns the kind for each response it sends back. Once we have found the right response, we just pick the first video in the
items array. We know that this response will exactly contain one element because we explicitly ask for a video with a specific id.
Now you might argue, well what happens when I pass an
id which is actually not a
video id. Well, in this case, the promise gets rejected and we dispatch a
WATCH_DETAILS_FAILURE action instead of a
WATCH_DETAILS_SUCCESS action. So we basically don’t end up in the
2.5. Youtube video response types
Well, there is actually one more thing we could do. We have a hard coded
string in our
find expression. This is not best-practise. Therefore let’s create a file where we define the different kind of responses we are working with. Like so we are more flexible.
- Create a new file called
Add the following code:
Now we can update our
3 Fetching video details in Watch component
3.1. Wiring up watch component to action creators
Let’s test out our new reducer. For this, we need to dispatch the
WATCH_DETAILS_REQUEST action inside
Watch. Let’s first pull the dependencies from our global
Redux state in by using
First of all, we pull the
youtubeLibraryLoaded from our
Redux state in. If the library hasn’t loaded yet, we cannot perform any requests.
We also pull in the
watchDetails action into our local state by using the
Finally we export our new component with the react-redux connect helper. Note that we are are also making use of the
withRouter helper because Redux and React router sometimes get in their way. We already covered this in the previous tutorial.
Let’s add the needed code inside the component itself.
fetchWatchContent function extracts the
video id from the current
URL. After that it starts the fetching process by calling
We make use of our data fetching logic in
componentDidUpdate. Note that we only attempt to fetch data when the we already loaded the
Youtube client library.
3.2. Updating App component
Remember that we are now using a
default export inside our
Watch component. Therefore, we need to update the
import statement in our
4 Wrap Up
Go to the
Home feed and click one video thumbnail. After that you should be redirected to
Let’s check out our store with the
Redux Dev tools extension.
Click on the image to see it in high resolution.
Nice, the video details are fetched and stored in our Redux store.
In the next tutorial, we will start making use of this data and actually show it in the
You can find the entire 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.