This course has been updated! We now recommend you take the Complete Intro to React, v8 course.
Transcript from the "Creating a Carousel Component" Lesson
[00:00:00]
>> Brian Holt: So let's get started here and we're gonna make a file called carousel.js.
>> Brian Holt: What we're gonna teach you here is how to do interactions. Like if I click on something to make something happen to my interface and store that in state, and kind of how it connects those things up.
[00:00:22] So we're gonna start here with Carousel which is a hard word for me to spell for some reason, .js. Every time I, it's like one of those words that when you start reading it and it just doesn't make sense to you. You kinda get in your head about, I don't know, right, at least I do.
[00:00:38] Okay, so import React from 'react'. It's the first thing I'm gonna do up here. And this is going to be a carousel of all the various animals photos, right? So that you can see all of the pictures that come with each animal. So class Carousel extends React.Component. Okay, and then down here you just export default Carousel.
[00:01:04] That's in general how I start every React component, because I often forget to put this export default, it's obviously very key in this process. So I tend to do that up front. I'm gonna write a render method up here.
>> Brian Holt: Which we'll get to in just a second.
[00:01:23] The first thing we're gonna do is we're gonna make our state object.
>> Brian Holt: Photos is gonna be an empty array. And active is going to 0. This is gonna be like the one that's currently showing to the user is like the hero image, right, the big image. So we're gonna start by showing him the first image in there, the 0 index, okay?
[00:01:49]
>> Brian Holt: Then I wanna show you another life cycle method that's actually brand new to React 16. This one is called get derived state from props, so this is gonna be a static method, getDerivedStateFromProps. It's a long one. And we're gonna destructure this and get the media object out of this, like that.
[00:02:18] Why is this so upset right now? Cuz I don't have it render return anything. That's annoying. So I'm just gonna delete that for a second.
>> Brian Holt: So let's talk about getDerivedStateFromProps. One, it probably is mostly self explanatory that you have props coming in from a parent, and you want to have some sort of derived data from the props, right?
[00:02:38] What's cool about this getDerivedStateFromProps is that every time that the props change, it's just gonna run this again for you so you can update the state. Which I think is pretty cool, it's just odd math kind of hooks into that life cycle. Yeah?
>> Speaker 2: Why do you have to call it static?
[00:02:54]
>> Brian Holt: I'm getting there, good question. First of all, if I delete this, it's gonna say, eventually it will give you an error saying like, hey that needs to be static from the linter, but let's talk about why this is static. So a static method doesn't actually exist on the instance of it, it exist on the class level.
[00:03:16] Which means that all carousels on your page, if you have 200 carousels in your page, you're gonna have one copy of this getDerivedStateFromProps, right? Whereas if I have 200 carousels, I will have 200 render methods, right? Each get their own copy of the render method. Now the reason for this being, is that getDerivedState is a static method that I can actually just call like this, Carousel.getDrivedStateFromProps.
[00:03:47] I can call it directly on it whereas I can't call Carousel.render because it doesn't have a specific render method until I actually instantiate a class. So I'd have to say const c = new Carousel and then I can say c.render like that.
>> Brian Holt: And the reason being for this is that, we can do it this way is because this just takes in some props and it gives you back state, so it's not actually operating on any sort of part interior.
[00:04:20] You're not gonna call set state or anything like that inside of it. You're just gonna take props and give back state, that's it. So that kinda makes sense? That's what static means in this particular case.
>> Speaker 3: Would you also want to avoid using this inside a static function?
[00:04:39]
>> Brian Holt: You have to.
>> Speaker 3: You have to avoid it?
>> Brian Holt: You will be referring to the carousel class in general, right? So if I said like this.render = 5, I will break every carousel.
>> Brian Holt: So, yes.
>> Brian Holt: Yes, if you remember from yesterday, the photos array has all the various sizes in it, right?
[00:05:02] And we had to narrow it down to just the one type that we cared about. And so that's what we're gonna do here, is we're going to take in all of the photos and narrow it down to just the photos we wanna have. So we're gonna say let photos = [ ].
[00:05:17] if (media && media.photos && media.photos.photo).
>> Brian Holt: photos = media.photos.photo,
>> Brian Holt: .filter. I'm gonna say photo and do an arrow method where we turn photo['@size']) it's gotta be in quotes. === 'pn'. And then down here return a new object of photos: photos or just photos like that.
>> Brian Holt: So again, filter, remember, is gonna go through, and it's going to filter out all of the ones that are not pn.
[00:06:22] That's what this little filter function does right here.
>> Speaker 4: What does pn mean?
>> Brian Holt: That's the size of photo that we're going to keep, it's from the API. Yeah?
>> Speaker 5: You were mentioning how this is a static because it doesn't change anything internally. You're just grabbing data from the props and providing state, but then even though you don't set the state here, this isn't setting your state up on the class level?
[00:06:55]
>> Brian Holt: So basically React is calling the static method for you, and it's using that data to merge into the instance. So React is internally using the static method that you provided, right?
>> Speaker 5: Okay.
>> Brian Holt: Does that make sense?
>> Speaker 5: So then does that, would that trigger a refresh like the said state would?
[00:07:11] Or I guess it would cuz the props [INAUDIBLE]-
>> Brian Holt: The props are changing.
>> Speaker 5: Okay.
>> Brian Holt: And I was trying to remember where it says this. So if I save this without static in there, React in the dev console will say, hey, this needs to be a static method.
[00:07:25] The dev build will, the production build won't. I think about a little break in production. Yeah, questions.
>> Speaker 3: So you getDerivedStateFromProps is a specific magic name? You didn't just make that up, and we're gonna reference it. React is looking for that name.
>> Brian Holt: Correct.
>> Speaker 3: Thanks.
>> Brian Holt: Yep.
[00:07:41] Yeah, there's a handful of them that React looks for, like Component getMount, Component willMount, getDerivedStateFromProps, shouldComponentupdate. Does this actually tell me, yeah, getSnapshotFromUpdate. There's a,
>> Brian Holt: forceUpdate, so there's a bunch of them that React has built into it. Now we have that. Let's go ahead and write our render method now.
[00:08:14]
>> Brian Holt: And do some more destructuring here. const { photos, active }, we're gonna pull that out of state.
>> Brian Holt: And we're going to return here div className = "carousel". Again, it's just I can never spell that word correctly.
>> Brian Holt: img src = photos, then we want to grab the active photo for the primary photo here, active.
[00:08:55] .value cuz that's where the URL is gonna be, and then the alt is going to be primary animal image, or something like that.
>> Brian Holt: Yeah.
>> Brian Holt: Our linter says that you don't wanna put anything like photo or image or anything like that because it's redundant because it's an image tag, so it's obviously an image.
[00:09:23] It's always a temptation for me.
>> Brian Holt: div className="carousel-smaller".
>> Brian Holt: And then we're gonna do a photos.map here, photos.map,
>> Brian Holt: And then we're gonna pull out both the photo and the index. Because we need to compare against is this the correct index or not?
>> Brian Holt: Now what I could do here is make this a function body and return right here, or I can use the implicit return.
[00:10:13] And so I'm going to put another set of parentheses here. Which is gonna make whatever I put here an implicit return, right? And now I can just start writing in my image tag here. So key = photo.value because we know each URL will be unique for each image, so that that will work for the key.
[00:10:35] The src will also be the photo.value. className will be equal to, and then now we need to set an additional active class, if this is the currently selected image, right? Because we want to like grey that one out and kind of show that it's the active image. So we're gonna use a ternary here, and say index === active, right?
[00:11:00] Because if this index here, if it's the first thing in here, and active is number one, then this should return true, right? So I'm gonna put question mark to show that I'm doing ternary. And put 'active'. And if it's not, then I'll put
>> Brian Holt: So let's see if I can get this to wrap really quick so you can see that a little bit better.
[00:11:25] I'll put the alt here in just a second. In fact, let's just do that really quick, alt =animal thumbnail.
>> Brian Holt: Okay.
>> Brian Holt: So this right here. Sometimes people struggle with ternarys, they're actually quite common in React because we use expressions everywhere. So this is a condensed if statement, right?
[00:11:52] This is the conditional, is index === active? Then after the question mark, if it's true, it's the first thing, if it's not true, it's the second thing, right? If this then this else this, make sense?
>> Brian Holt: So if it's active, then it gets the active class, if it's not the active one, then it gets no class.
[00:12:18] It's got no class.
>> Brian Holt: You'll see this a lot with React, stuff like that. You can also use a library called className that basically is a helper library for kind of condensing these things down to making it little bit easier to read. We're not doing very much of this, so I just preferred to use a ternary in this one case.
[00:12:45]
>> Brian Holt: I probably use and abuse ternary as for being honest. Any questions about this?
>> Brian Holt: Okay, so now this is enough to render. Its not interactive yet but this is enough for it to render. So let's go put this in first to the Details page.
>> Brian Holt: Up here, actually we can even just start go writing it, I love this part about VS Code.
[00:13:13] First thing instead of div.details, we're gonna put a carousel component. And I'm just gonna auto import that from,
>> Brian Holt: Carousel, and I'm gonna say media = media.
>> Brian Holt: Like that, and I guess I have to go pull that out as well.
>> Brian Holt: So what I did here, pulled media out of state, and then I add at this line number 53 right there.
[00:13:46]
>> Brian Holt: You have to import Carousel at the top which VS Code did for me.
>> Brian Holt: Okay, and then here at the top, Carousel got imported from Carousel right there.
>> Brian Holt: So now hopefully, we go over here to Adopt Me. We click on to go see Uta, we can see all of the Uta's pictures
[00:14:16]
>> Brian Holt: So you can see now that we can see all of the pictures that are coming in for this particular animal. It's not interactive yet, right? We still gotta go make it actually interactive so you can change it, but we should be seeing that.