React Native, v2 Lists
Transcript from the "Lists" Lesson
>> This implementation is pretty good for the four colors that we have. But what if instead of four colors we had 10, or 100, or 1,000? This solution just wouldn't scale. Now, if you're familiar for how we render these things on the web, you might be tempted to have a color array and just map over it to render a bunch of colors.
[00:00:25] In Native development, you should never use a map to display an array of items. And this is due to performance. Because basically the mobile phone will render every single thing that's on the screen. So if you have an array of 100 colors, it will try to render all of them.
[00:00:44] And it will try to rerender all of them whenever the component tree renders, regardless of whether the data has changed. So in order to render lists, we have special components in React Native that you can use to display them. And these are called FlatList and SectionList. So whenever you have an array of data that you need to display, you should probably be using one of these.
[00:01:09] I refer to this documentation quite a lot. So this is the React Native documentation for FlatList and SectionList. And on the right, it has all the properties that there are available, and same for SectionList. I'm going to go through some of this in a bit, but let's look at how it works first.
[00:01:29] There's a lot of configuration options for FlatList, but at a minimum, you need to give it 3 props. The data, which is the array of items you want to loop over and render. The renderItem function, which is a property that you pass in a function that tells the FlatList how to render each individual item.
[00:01:49] And then the keyExtractor, which basically gets each item and you have to return a unique index for that item. So you can go ahead and click on this if you want to play around with it yourself. But this is an example of FlatList that I created on Expo Snack, which usually appears here.
[00:02:11] It doesn't at the moment. So Expo Snack is basically like JSFiddle, but for React Native, which is pretty cool, but it's a little bit-
>> You need to run it?
>> Busy, yeah, it's a little bit busy. Yeah, okay, there we go. So this actually renders on the web, so you need to be wary of it.
[00:02:35] It's not actually how it will look on the phone sometimes. If you want to display it on a device, you can just press here and scan the QR code. But I'm just gonna look at the web one cuz I don't care for this one. All right, let's look at what it looks like.
[00:02:51] I don't think I can make this smaller. Well, hopefully you can see most of this. Okay, right, so this is my app. And the only thing I'm returning from this app is a single FlatList, which I've imported from React Native. Now I've got a data which is an array of foods.
[00:03:15] These are just the names of the foods, an array of strings. And then for the keyExtractor, it gets passed the item, which is whatever this is, which could be an object. And then I need to return what's the key for that item is. So this needs to be unique.
[00:03:30] This actually also has the index. So if your item doesn't have anything unique, you can use the index, as well as something in the item to create something unique. And then the main thing we have here is the renderItem, which is basically a function that takes the data element where data.item is one of these elements.
[00:03:56] So usually you actually end up doing this and destructuring. But it can be a little bit difficult to read when you're first looking into it. And here I've got a food component, which basically just has a view and a text that renders the food name. And FlatList and SectionList are actually very cool in that they are completely optimized for the web.
[00:04:25] If you have 1,000 elements in your array, it actually only renders the ones that your user can see. Let's look at a SectionList example as well. All right, so this is very similar to FlatList. They've actually shared some of the properties. The difference here is that we can add a section header in between a bunch of the items.
[00:04:53] So instead of data, notice that the property we're using is called sections. And the data element is an array of objects where I've added a title. It doesn't have to be called a title. But the only key that you really need is data. So this has to be an array of objects where one of the keys is called data and the data is basically the content that gets rendered in a section.
[00:05:19] The keyExtractor works the same, but notice that the keys don't get extracted from this, they get extracted from this. So that the item that you get is, for example, apples and broccoli and not this entire object. Then we have a renderItem, which works exactly the same as in a FlatList.
[00:05:43] And, finally, something that we don't have in a FlatList, we have a property called the renderSectionHeader. And this basically gets the section, in this case, the whole section. And we use this to display the title. Now, SectionList has had these because if you use it on the actual device, the sections actually get sticky, so they stay on the screen until you parse the section, yes.
>> So the SectionList only works with array of object?
>> Yes, yeah, so they both need to have an array. But for SectionList, you have to have an array of objects. So I've just listed some of the properties that FlatList and SectionList have that I use most frequently.
[00:06:35] So you might want to look into. Firstly, we have the ItemSeparatorComponent. So this is, you can pass in either a function or just the JSX components. And it renders a custom separator between your items. So for example, if you have a line or some kind of image or something custom that you wanna render, instead of adding it underneath each item, you can use this ItemSeparatorComponent.
[00:06:59] Then there's a ListEmptyComponent. This is actually really cool because if we did ListEmptyComponent, and I'm just going to do a text that says List Empty. Cool, and now instead of foods, if I pass in an empty array, it will automatically render ListEmptyComponent. So this is really handy if you do data fetching because you don't need to worry about going, if this data is empty, then render this, otherwise, this.
[00:07:37] All you should do is just add this ListEmptyComponent here. Then there's a ListFooterComponent. As you might imagine, this is something that gets rendered at the very bottom of your list, regardless of how big the list is. So I'm gonna add this back. ListFooterComponent. Cool, yep, so this gets at the bottom of the list.
[00:08:07] And then there's an equivalent ListHeaderComponent, Which, Gets rendered at the top of the list. Here we're actually seeing what this FlatList would look like in React Native web. I'm gonna show you what this looks like on my actual phone. So I didn't add a SafeAreaView here, which is not good of me.
[00:08:36] I'm gonna add one quickly. Yeah, so one thing to note is that this scrolls, but the list header and list footer scroll with the content. Whereas if I added a bit of text outside of that list, Yeah, then this bit doesn't scroll. So this is something to bear in mind cuz sometimes you might want to have the header just one thing be sticky.
[00:09:26] In this case, you don't wanna use the list header. Another property that you'll probably not use everyday, you'll definitely not use every time but is good to know is the extraData property. You can pass anything in there. It can be just a single item or an array. But basically, the FlatList only gets rerendered if the data changes.
[00:09:46] So if the renderItem function that you have renders different things based on something in your environment that's not the data, you'll have to put these things in the extraData. So that's something that might save you some hours of debugging. I wish someone had told me before I spent hours on this.
[00:10:04] Another thing, I think someone asked this on the chat, which is can you render things horizontally? And FlatList actually has a prop called horizontal, which takes true or false. And this renders the list horizontally rather than vertically. Another thing that's cool is that it has a numColumns property, I think I'll just do numColumns to 2.
[00:10:31] Yeah, it just renders these in a column, which is so handy because on the web, this is a huge hassle. And you can pretty much make this any amount of numbers. And finally, onEndReached, you can pass a callback here, which will get fired when the user has scrolled to the end of a list.
[00:10:55] And this is handy if you're doing data fetching here or pagination, so you'll know when to paginate. There's also attributes that let you customize when this gets triggered, how far in advance do you need to know.