 Hey, welcome to day 22 of React Holiday, this series where we're going through React and suspense and hooks. This has been super fun. And I can't believe we're kind of getting to the end. Now, this is a weekend video. So, typically in these weekend videos, they're a little bit longer. And I do a lot more of the code motion. And that doesn't make sense when I'm trying to do one topic at a time. Now, the big concept that I want to introduce today is talking about how to think of components as an encapsulation of style. Now, this is different from the way that you think about like styling. So CSS, CSS modules, utility classes and CSS, CSS and JS, inline styles, any of those options that are available to you as a React developer, this is different. This is a way of thinking about the component model and how that can close over any of those implementation details. So maybe use all of those systems like this, these patterns will help you manage your application as it grows and maybe you decide to choose to transition from one type of styling system to another, et cetera. If you want these principles about how to think about components as encapsulating or closing over style, you're really going to be in a good spot. So I'm going to go over a bunch of, we're going to get there. So we're going to do a bunch of code transformation. This is going to be a longer video. So if you don't have a whole lot of time, maybe come back to it. But this could be really valuable for you as your app grows. So let's get into it. So the first thing is that I've moved this type up a little bit. And the only reason for that is that I want this block of code to be closer to this area. So I don't have to be jerking around the screen a lot. That's the only thing. Second of all, yeah, there is no second. So what we're going to do is we're going to dive into what we have. That shouldn't be there. So right now we have an unordered list and we're mapping over the types to get a type and then we're using a list item and type.name. What we'd like to be able to do is use a component, maybe a type. What we'd like to be able to do is use a component, so a type item that can encapsulate some of those style details. So let's do that. So we'll change this to type item if I can type it. And now we just need to define that. So we will say function type item, take props and return a list item and spread out the props. Okay, perfect. So that works and it's doing exactly what we've done before, but we've added this abstraction for the item. Now let's go ahead and style that. The model that I'm using for this site is effectively these end up being buttons and you can click on a type and it'll navigate to a page that has everything from that type. So we're just going to style it kind of close because we don't have time to actually add that functionality to this app. So we'll start with a background color of gray and we need to change the display. So we'll make that display inline flex. Cool. We'll add a little bit of margin to the side there so they separate a little bit. So margin right to five and then M is just a measurement that's relative to the font size. So this is about four pixels. And we'll do a border radius. Oh my gosh, about the same point to five M. And let's give her give give it some padding point five M on the top and bottom and point 75 M on the left and right. Okay, cool. That is maybe even go a little bit further. That's looking pretty good. Pretty good. And we'll actually use some styling here and take that padding off. Awesome. Okay, that's looking good. I'm going to save to get some of the reformatting on this text here. And one last thing, we're going to do color white to get some contrast against the colored backgrounds. Now, so the first thing is how do we make this variant? So the first option would be to use a ternary, which we have seen in the past, which looks something like this. We would take a type, check it and say if the type is grass, well, then we want that to be green. Otherwise, we'll do gray. Now, we don't have the type available to us. So we can make that available. So we say type equals type dot name. Okay, so we're getting that right off here. We're passing that along. So in order to use that, we need to destructure that off of props. Now, something that I find useful is sometimes to change this to native props, especially if I'm using a like dom native element here. It helps me to be able to distinguish between like everything else is a native prop like so this could be ID, class name, data attributes, etc. And then these are the props that are defined that I've defined for this components API. And being able to separate that mentally is really important. Now, something that we have a problem with right now is that we have, we can only have one type. Now, this ternary works terrifically for booleans when it can be only one or the other. However, we have this is innumerable, we could have any number of things, any number of types, not only the however many types there are in the system right now, but that could be a growing number of types. So what do we do about that? Well, we could use a function. So so let's see, let's call this get type background or let's just call it color, get type color of type. Now, I'm going to define this function inside of the scope. So I actually have access to type. But in terms of kind of future proofing your code, passing it as an argument is a really great idea because if I end up needing this function that I define now elsewhere in the module or elsewhere in the system, I can easily move it out when I don't rely on scope and I actually just take all the data that I need as arguments. It's much harder to actually make that transformation later when I want to move that out to actually make it take an argument. I know that's kind of high level, low level, I don't know. You'll know when you have a problem with it. So function get type color and that's going to take a type and return what we had before. Okay, cool. Now, everything works the same way that it did before. It's just that now we have inserted a function abstraction there so that we can kind of extend this with more options. Now, something I think would be a natural fit for this is a switch case. Now, I am notoriously bad at writing a switch but if you need a switch, as I often have to Google for and definitely did this time, you can search for one on MDM. They have an example right at the top because I think a lot of people forget how to write switch cases. So the way it works is something like this. So we would write switch and that's going to switch on some variable. So that'll be type and then we give it a block and we have cases. So in this case, the case is going to be is it grass? Okay, we use a colon there and return green if it's grass. Okay, cool. Perfect. Now, we need to figure out the other part. So we can have a default in this case and we want the default to return gray. Cool. So this is exactly where we were before and now we can add an additional case for poison, which is purple. Okay, so what have we done? We've inserted a function and now we have given that function the ability to handle multiple cases. Now, you've probably heard that like doing a break in each of these is super important and it would be if we weren't just doing this function and returning right out of it where these returns are basically ejecting at this point anyway. So the break is just redundant. You can put it there if it makes you feel better. But I think even our linter is saying that the code is unreachable, unreachable code. So you don't need to put those breaks in there. Now this is not bad. This is actually looking pretty good. And at this point, job done, right? You can come in here and add additional types as you need. No problem. Now this whole thing is about better future proofing your code, right? So what I want to do is I want to really talk. I mean, we're getting really nuanced here, but talk about how you can improve this code long term and give yourself put these options in a place that are going to make your components most flexible. Now, a problem that I have with this is that it breaks one of the principles of solid. Now, solid is an acronym for like really malleable code, I guess. And the O in that stands for open to extension closed to modification. So open closed principle is what it's called. And the idea is that you need to be mindful of things on the edges that know too much. And this component knows too much, really. These are, this is like a system level knowledge, right? Like what grass and poison colors, like the color mapping. So having it at this, at this level, it's very likely that we're going to have to duplicate this information across the system. And so we might have to like just duplicate it, or we might end up having to move this into another module. And information like this should not really exist at those leaf edges. Now, right here, like we have a very small app, this is probably fine. But in a bigger app, you need to be mindful of these moments where you have a component at the edge that knows way too much. So how can we solve that? First of all, I'm going to change this back to only be gray. So I want this to only have the default representation in here. So when we have type item, that's going to always be gray. Now we can take this out. Okay, so we're going to take that whole thing out. And the component still works. And we're going to insert it here. So watch, watch carefully. Okay, so we're going to insert it there. Now I don't want this function wrapper here anymore. Okay. And we're gonna have to change this to a block, because we have a switch case in here. So we can't just use like kind of like a default return. Now this is the default case. Okay, so I want to take that. And I want to use that as my default case. I want to return this component, not just the color, or return this component. And because I don't need the I'm not using the type data for anything, we can actually pull that off and just go back to props. Okay, so we are again, removing that API that we created for this component. And now we're just encapsulating these styles. Okay, dragon so far. Okay, so this is great. So now what do we do with these green and purple cases? Okay, glad you asked. So I am going to do the same thing, but instead of depending on this type item, to have that knowledge and switch on type, I'm actually going to, at this higher level, actually provide that data to it. I'm going to tell it what it should render like what it should look like. So we'll do that by saying style. And we'll say background color is purple. That's for poison, right? And then same thing for green for grass, we're going to return this item with green. Now, you're looking at this and you're saying nothing changed, right? So we have this whole they have this whole setup now, we're we're giving it style, and nothing changed. And you're totally right. And the reason that is, is because we are not, this is not extensible, it's only going to apply these styles and it kind of sucks up all the rest of it. So what we need to do is this, we're going to, again, to structure this, we're opening this back up again. And now we'll take style and spread style out here. Now I've obviously not done something right because this isn't this isn't working yet. Ah, I know what's going on. I am switching on type, not type that name. So I had that old switch case. But really, I need to be pulling the type name off. So okay, we finally got it. Now, you're looking at this and you're saying, well, yeah, now this is a whole lot messier. So that doesn't seem better, right? Well, it actually is because now what we can do is we can create these as components. So personally, I would probably leave this as is for as long as possible. And the cool thing about this is that we could create some kind of module for these, like, you know, if we wanted to import a module with all of the like color mappings, we could say types dot grass, and that could that could be a variable for green. If we have like all the types. And then we would just return this element. So right now it's all it's all pretty literal. But again, future, future ideas. Now, the cool thing about this is that we could we could then start to create these as first class components. So if we did a grass type item, type item, we could then define that as a component that we could reuse places. So function grass type item, props, you know, it's kind of annoying not having my my keyboard shortcuts in this environment, having to type a lot of stuff that I don't usually type. Okay, cool. So now here, we're going to have this grass type, and it is going to render a type item. Okay, it's going to spread out all the props so that we can get the name on there. And it is going to apply that style green, which means that we can delete it from here. So in the end, we could have a component, we could have a block that just looks like, hey, for each type, we're going to switch on type. If it's grass render the grass type item. If it's poison render the poison type item and otherwise just render type item without, you know, any without anything. So this is this is really awesome, because then we start to have components for each of these things. Now, only this is an exercise up to you, but you can actually make these dynamic so that you don't have to have this switch case tag. But then you could just use that and then render the, you know, the component type with the name, it's all pretty cool. But I'm going to leave that as an exercise for you, because this video has already gotten way too long. But as a recap, it is so good to think about components as a way of encapsulating style. When you do that, try really hard to limit each component to one concept or one thing and try to extend it by wrapping it so extend it from the outside. Instead of this having a lot of smarts about all of the like inside just making that bigger and bigger and bigger and bigger, try to wrap it with the functionality that you want. So right here, this is always going to render gray. But we've made it extensible because it can take style, right? This could be a class name, this could be whatever you want. But we're, you know, extending it with style right now. That means that down the road, we can render a type item and use all of that styling that we've inserted, but then also have it be totally open to extension. So as we get new types, we just define new components that have the one preference that they need to care about. So, you know, this becomes really easy to extend. So poison, right? And this is going to be purple, of course. All right, my computer's frozen. So obviously that's as far as we're going to get today. But I hope that this was helpful. I know that it's a lot of concepts all jammed in there, but this is something that I wanted to cover because I think it's so important. And I think it's something that a lot of apps fall down on is putting these kind of inserting too much information into these edge components. When really they should that that information be should be wasted above. And those components should just be extended or wrapped around. So thanks for hanging in there. No, man, I really, I really value your time. And I really do hope that this was valuable to you. I'll see you tomorrow.