Now of course here I'm using a scroll view and you learned that a FlatList is better if you have a
list where you don't know how many items you'll have in there.
Now for our game, a scroll view actually will be fine because yes, we don't know how many items it will
be and theoretically, for guessing very poorly, we'll have around 100 items in there but that will happen
almost never and therefore typically this list will not hold more than 10, 15, 20 at most, items
and therefore this will very likely never cause us any performance issues
and using a scroll view here is absolutely fine because yes, it's a list that holds multiple items, that
will exceed our screen boundaries but it will rarely be a list with a lot of items, it will never be
a list with more than 100 items due to the way our game works.
So scroll view would be fine here but in case you still want to use a FlatList, let me show you this
as well.
For that, we can add FlatList here and that of course means that we need to import FlatList from React
Native,
so here, I'll import FlatList like this
and with FlatList imported, you learned that FlatList takes a data prop which points at the data
that you want to feed in and in our case here,
that would be our past guesses array and that you then have a render item prop which allows you to
output the items for every item in the data you are feeding in, so output the components for every item in
the data
and here I can point at render list item which should be called. Now
right now this won't work for a couple of reasons. For one, render list item expects two values
but render item here on FlatList will only forward one item and that's that item data which holds information
about the index and about the item we're about to print.
The other thing that will cause us problems is the key.
You might remember that FlatList expects to get objects in the array you're passing in where each object
has a key property it can extract and use as a key for efficient re-rendering.
Now we don't have an array of objects here, we have an array of numbers and that's not going to work.
Now we can add a key extractor here to FlatList to override its default, key extractor takes a function
which gets our item in the end and then we have to tell FlatList where to find our key and by default,
it looks for item.key or for item.id,
here we want to tell it the item itself is key.
Now FlatList however wants a key which is a string and not a number,
otherwise it'll get a warning.
So the next thing we have to do is the past guesses we're managing should be strings and that's no problem
because we're only using them for printing them to the screen anyways, so we don't really care if they're
technically stored as a number or as a string and hence here when we add a new guess, we can simply call
toString which is a built-in Javascript method on the number to convert it to a string type and do
the same for the initial value of course. Here where I add my initial guess, call toString there as well
and now we have strings and they can be used as numbers
therefore. Now as I said, render list item is expecting the wrong arguments though, numOfRound won't
work like this, value also won't work like this, instead we're getting the item data and we can
still expect an extra argument though,
this however then has to be expected as the first argument because we can now simply go down to render
item here on the FlatList and bind arguments that should be passed in, so we can add additional arguments
besides the default argument which will be passed in. Now bind expects this as the first argument so
that we set what this should refer to in the function we're calling, we don't care here so I'll just
add it to this,
you could also set it to null, it doesn't matter.
The second argument we add here then will be the first argument received by that function and that should
be our round number which should be
pastGuesses.length. Previously, I deducted the index here but that doesn't work anymore because I
don't have access to the index anymore,
we're not mapping manually. So I'll just pass the length in there
and the good thing is I can get the index inside of render item out of the item data.
This default argument will also be passed in by React and the default argument automatically is passed
to last argument.
So the first arguments will be the arguments you set up in bind,
in this case, that's only one argument,
our number of rounds or our length of the array and then any default arguments which would have been
passed normally will be added as additional arguments at the end of your argument list here.
Now here, number of round also isn't a fitting name anymore,
instead it's the list length, that sounds like a better name because that's what we're getting
but then here we can calculate our number of rounds by using list length and then by deducting
itemData.index because the item data you're getting automatically by React Native is an object which also
has an index property which is the index of the item you're outputting and you also get itemData.item
and that's the item itself which in our case is the guess.
We now also no longer have to add a key here because that keying will be done by React Native thanks
to the FlatList. So that was a lot of work,
now we should be able to output a list again.
So let's save this and let's give it a try
here and that seems to work,
however of course we lost the positioning now. Previously what we did is we added content container
style, styles list here to the scroll view,
the good thing is you can do that on the FlatList too. Whilst you can add a style just like on the scroll
view, this style allows you for example to add a margin around the list but it doesn't allow you to align
the content inside of the list. For that
instead, use the content container style which is supported by FlatList as well
and therefore here, we can also point at styles list and therefore this should now just work as our
scroll view did before.
So let's give this a try and you'll see we start at the bottom here and we can now start adding items.
Now let's see if scrolling also works as it should,
yes it does and we can see the latest item and the oldest item
and yes there is something wrong with the positioning of the items in the list item and
I'll come back to this but generally, this works. Let's also test it on Android,
so there
let's start guessing and hope we don't solve this too early,
no, that works
and here, we can also scroll as you can see. So that works with the FlatList as well,
now what about these strange distribution of content here in our list items?
Well you'll notice that the list items themselves are bigger than they were before.
The content is distributed as if the list item would end here though and that's indeed the problem.
We have a width of 60% of the list item and our content respects this but our borders
strangely enough doesn't.
To fix this strange FlatList behavior, what you can do is you can go to your list container that holds
the overall list and set the width there to your desired list width at the end, like let's say 60%
and give your list items a width of 100%.
So now the list container overall is smaller, is less wide and therefore the list items assume that width
and have the same width
and since you rarely have to use case where your list container needs to be wider than the list items
because what else would be in there in the list container, that should be a fine solution.
Now if you do that, you'll notice that the width looks better but actually, the positioning now is a problem.
Well since we now have the width controlled on the outside list container, we can get rid of align
items center here on the list itself,
so list, don't forget, was the style added to content container style.
We keep the style there but I removed align items center because there is nothing to center now,
we have the width set on the list container not on the list items,
so thanks to them having 100%, they're centered automatically because they take up the full
width anyways and therefore now if we give this another try,
this seems to work way better and the list items are actually laid out in the way they should be.
So if we have another around here which maybe takes a bit longer,
yes,
looking good, then here we can see we get the same behavior as before, we get the nice style and we also
worked around that different behavior FlatList gives us. Let's also give this a try on Android here and
start a new game there,
oh this will not be a long game,
long enough,
so there also, everything works as it should.
And this is how you could do this with FlatList, as you see works a bit differently, we have to work
around its different behavior there
when it comes to adjusting the width of the list items but in the end, ultimately this now also works
and therefore you now learned how to lay your things out with FlatList, with scroll view, what's special
about these list views or those scrollable views in general and how you can still layout your things in
the way you want.