Add Conditional Styles to React Native With Classnames
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the Building React Native Apps for Mac course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Building React Native Apps for Mac, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
[00:00 - 00:08] So far we have style or application quite nicely. And it's pretty straightforward because we haven't gone into more complex cases .
[00:09 - 00:22] But as your application grows, you will start facing some subtle cases. And if you don't handle them properly, then it might get too complex to think about your styling and your state and your components themselves.
[00:23 - 00:37] So we're just going to explore this a little bit and how we can solve this on the long run. So let's say, for example, here on my book container, I want to change the title color based on the name of the book.
[00:38 - 00:49] So we already explore one technique of doing this, which is I could create a variable outside of my component itself, right? And I can call this title color.
[00:50 - 01:07] And here I can do some check. Let's say, for example, if the title includes the string Lord, and I just declare my colors in here.
[01:08 - 01:18] But this is quite cumbersome to do every single time, right? Especially if your component is going to grow, you're going to go back and forth, back and forth and create a bunch of styles.
[01:19 - 01:30] Sometimes you might get a little bit lazy and you might try to do something like this instead of creating the variable outside of the component. I'm just going to put it in line.
[01:31 - 01:37] And this effectively works. But as your component grows, you might start doing a lot of this right here.
[01:38 - 01:48] You might add some some other condition. Let's say instead of red, I also want it to be.
[01:49 - 01:54] I don't know. I want the fonts to be bold, right?
[01:55 - 02:08] But you kind of see or you kind of notice already as you go piling this up, it 's going to get harder and harder to understand your styling. And if it's embedded within all the other logic, it gets even harder to read.
[02:09 - 02:13] So this is definitely not scalable. So we're going to do something against this.
[02:14 - 02:25] In order to solve this, we're going to use another package. Let's add the dependency to the class names package.
[02:26 - 02:38] So the class names package is just a small utility that allows you to declare your styles as an object. And at the end, it takes a Boolean value, right?
[02:39 - 02:53] So the mapping is from a string to a Boolean value. And then it concatenates all the values or all the keys that have a true value.
[02:54 - 03:06] So let us just try it here. And I'm going to import Cn from class names.
[03:07 - 03:25] And instead of doing this, what I'm going to do is I'm going to pass inside of the tail in function, the Cn function. This one takes first of all any number of arguments.
[03:26 - 03:38] So I'm going to pass the first part of my styles because those are static, those don't change. Then I'm going to pass an object.
[03:39 - 03:49] Inside of the object, I'm going to pass first this one, right? Because this is the first part of my ternary operator.
[03:50 - 04:01] And because these two ternary operators are the same, they're both checking for the same condition. I'm going to add the bold font to it.
[04:02 - 04:13] And then I'm going to create a condition here. I'm going to place a condition in here that's going to evaluate once the component runs.
[04:14 - 04:27] I'm going to do something similar for my other styling. But this time I'm going to negate the property or the condition.
[04:28 - 04:35] And here, yeah, that's fine. I'm just going to change the text.
[04:36 - 04:42] And if I save it, you can see it now works. So let's change this.
[04:43 - 04:46] How do we test this? Let's change our book.
[04:47 - 04:49] Let's go for the name of the wind. And there you go.
[04:50 - 04:57] So you can see this is a lot more readable, right? You can quickly check for the condition at the end.
[04:58 - 05:09] And you just know that this is going to be appended. We can shorter this even more because at the end of the day, you're going to be combining both of them quite often, right?
[05:10 - 05:24] So there's no need for you to import each of them separately and applying them every single time. So I'm going to go to my tailwind file and I'm going to create or I'm going to export another function.
[05:25 - 05:32] I'm going to call this CW. This is the combination of class names plus tailwind.
[05:33 - 05:41] And this one's going to take undefined number of arguments. I don't care too much about the types right now.
[05:42 - 05:48] If you want, you can try to extract the types, but it doesn't matter. And I'm just going to do the same, right?
[05:49 - 06:06] I'm going to apply CN to TW and I'm just going to pass all my arguments into it . I also need to import my CN function and that's it.
[06:07 - 06:28] So now instead of importing TW from my package, I can just import CW and I can directly apply it here, which means I don't need this wrapping and this wrapping and it still works. All right.
[06:29 - 06:32] You could go even further, right? And do it on the component level.
[06:33 - 06:50] So create wrappers for all your base components where the style cannot only take an object, but whenever it takes or whenever it takes the final object, it directly runs it through the CW function. But that's an extra, we don't need to do it.
[06:51 - 06:54] That's good enough for our purposes. You