Behavior Encapsulation and React Native Reusable Components
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:15] So far, we have written a single huge UI react component, right, which is our book list. However, it's important to talk about how components are actually useful.
[00:16 - 00:27] And they actually have some benefits. One of the major benefits is behavior encapsulation, because each component is meant to represent a single chunk of the UI.
[00:28 - 00:37] It's quite easy to abstract and to think about it. Nothing in a global state, but they actually have their own internal state and logic.
[00:38 - 00:46] So that kind of helps you break down your UI. Another benefit is precision updating of the UI.
[00:47 - 01:05] This is not something that you do, but actually that reacts to those for you. So instead of redrawing or changing the entire screen that you present to the user, you kind of just let react, update certain parts of those screens.
[01:06 - 01:28] And the most obvious benefit you could say, once you have encapsulated your UI into reusable state or into separate components, is reusability, right? If you have designed your components properly and their APIs, you should be able to use them throughout your app, right?
[01:29 - 01:43] You might allow a little bit of customization, but you don't have to reinvent the wheel every single time that you want to create a new screen. So in order to illustrate this point, we're going to create a reusable button.
[01:44 - 01:51] We're going to take our current button component in our screen, and we're just going to abstract it away. So this is an exercise.
[01:52 - 02:00] This should be fairly simple. So I'm going to create a new folder.
[02:01 - 02:12] I'm going to call this component. And instead of components, I'm going to create a button.component.tsx file.
[02:13 - 02:22] So once again, I'm going to take the code from the lesson, and let's just walk over it. So I'm just going to ignore the import for now.
[02:23 - 02:30] Don't worry too much about them. And I'm going to focus on the props, right?
[02:31 - 02:49] So the props are pretty much the API that your component is going to have to the outside world. So the first thing that you will notice is that I have imported the touchable opacity props, which come from React Native.
[02:50 - 03:00] So this is fairly important because it's a button. And a lot of the properties that a button takes, they are already defined for you.
[03:01 - 03:14] So it's actually smart to see if you can reuse or at the very least, keep a very similar API to the component that already exists within the platform. Because otherwise, you're going to go chasing names of the time, right?
[03:15 - 03:28] You're going to have to open the component or you're going to have to rely on auto-completion to kind of know what props your component takes. Whereas if you keep it mostly similar at some point, you will just learn it, right?
[03:29 - 03:40] It's one of those things that over time it gets imprinted on your brain. So I'm just going to take all the props from a touchable component, which is defined by React Native.
[03:41 - 03:45] And I'm just going to extend. I'm going to create on top of those.
[03:46 - 03:53] So as my first prop, custom prop that I'm going to pass to a button is the title. Fairly simple.
[03:54 - 04:00] It's just a string. Then I'm going to use this pattern.
[04:01 - 04:10] Each button is going to have a type prop. And depending on which type it gets passed, it's going to have different styling, right?
[04:11 - 04:15] But basically in your app, you're going to have a bunch of different buttons. Sometimes they're going to be colored.
[04:16 - 04:19] Sometimes they're going to be flat. Sometimes they're going to be red because there's a dangerous action.
[04:20 - 04:31] You could delete something and so on and so forth. So you don't want to have this tool spread around because again, at some point, you're going to end up chasing buttons all over your codebase, right?
[04:32 - 04:45] So you kind of want to put everything within one single component. And in order to select which type of button you want, this is a pattern that works fairly well.
[04:46 - 04:53] So the last and final prop is a style prop. And this is particularly useful for those one of cases.
[04:54 - 05:10] You know, sometimes you have a button in the screen that needs to look a little bit different, and it needs to have a different color or something. So instead of creating a complete new style, just for that one use case, you can actually allow for some customization, right?
[05:11 - 05:16] If it's necessary, then you can do it. And that's pretty much it.
[05:17 - 05:26] I think that's the only interesting thing that we're going to do in this button . I just take the, I just strike my three properties from the props.
[05:27 - 05:39] And then I just take the rest of them, which are all the touchable opacity props. I'm just going to pass all the touchable opacity props to a touchable proper touchable opacity.
[05:40 - 05:50] And inside of this, I'm just going to just fix this. That doesn't fix it.
[05:51 - 06:02] All right, because it can be undefined. How can we fix this?
[06:03 - 06:14] Well, let's just say you need to pass this. All right, so, and then I just pass it to my inner container for my view.
[06:15 - 06:19] And that's pretty much it, right? So I have defined in my two different styles.
[06:20 - 06:30] So what I'm going to do, one more time, I'm going to create my index.ts file. I'm going to export from my button component.
[06:31 - 06:46] And on my books container, I'm going to replace this one with my button. And I'm going to tell it, you are now, the title is add.
[06:47 - 06:51] And you have a primary type. There you go.
[06:52 - 07:09] It's not super pretty, but it doesn't matter. So you probably wondering, you might have noticed that how do you evaluate what 's a correct API, right?
[07:10 - 07:18] How do you evaluate what's good processing from bad processing? Or how big should a component be?
[07:19 - 07:28] To be honest with you, there is no right answer here. It's one of those things that as you go developing your application, you will kind of realize, you know, some components might get big.
[07:29 - 07:38] They might start big and as you develop, it's like, oh, I have to break this down. Or they might just grow over time and you realize, well, you know, this is now way too large.
[07:39 - 07:42] I kind of need to break it down even more. Or you will make some mistakes, right?
[07:43 - 07:54] You will create a certain interface for your component and then realize it's too hard to use, right? You end up passing 20 things and still you don't understand really what's going on.
[07:55 - 07:57] So it's really hard. There is no hard rule here.
[07:58 - 08:04] I can give you three tips though. One is you want to avoid processing as much as you can.
[08:05 - 08:12] That is, you know, don't make it take 100 parameters in order to work. That's just complicasting at some point, right?
[08:13 - 08:20] It gets hard to reason about all your components and all the props and where they have come from and where they go in. So try to keep it simple.
[08:21 - 08:26] Try to divide. If you have too many props, try to divide your component even further.
[08:27 - 08:41] The second advice is avoid excessive nested, prop passing, right? If you have four different components, you know, a parent and a child and a parent and a child and another child.
[08:42 - 08:51] And if you pass one component right from the parent all the way to the bottom and not use it in a way, right? You're just passing it because that component needs it.
[08:52 - 09:05] Then that also is an anti-pattern that gets really hard to refactor at some point. If you have that kind of thing, I would suggest don't put it as a prop, put it in your mobic state or put it in a hook or something like that, right?
[09:06 - 09:26] Like extract it from prop passing and make it directly accessible to the child component. Even if it's just one, sometimes it might be worth to do these changes for one because once you change something, then you have to touch four different components that may not have to do anything with your changes and that just gets hard.
[09:27 - 09:43] And the third tip is names. Like we saw in the button, I'm reusing the touchable opacity props because I have seen people who, you know, they come up with their own kind of names and then it's like nobody understands anything, right?
[09:44 - 09:55] Even if you at some point made a gallery of all your components that you create in your application, there's just too many of them, right? Some people want to name this type.
[09:56 - 10:01] Some people name it style. Some people name it, I don't know, primary, right?
[10:02 - 10:06] They put it as a Boolean or something like that. So again, it gets complicated.
[10:07 - 10:13] What you want to do is just try to keep it simple, try to reuse as much names as possible and on the long run that pays off.