When to Use Keys - Flutter Widgets 101 Ep. 4

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] EMILY: Hey, I'm Emily from the Flutter team. In this video, we're going to talk about using the key parameter on widgets. If you're wondering what the heck a widget is, I recommend going back to the first video in the series, where we introduced the building blocks of Flutter. Keys preserve state when widgets move around in your widget tree. They can be used to preserve the user's scroll location, or keeping state when modifying a collection. In this video, we'll cover three things-- when you need keys, where to put them in your widget tree, and which key is right for you. [BELL DINGING] So when do you need to use keys? Most of the time, you don't. But if you find yourself adding, removing, or reordering collection of widgets of the same type that hold some state, it's key time. No, key time. An example of this is a to-do list app. When using the app, you want to reorder the items based on your to-do list based on priority, and then remove them when you're done. Another example is the Hacker News app in the Flutter Boring Show. Adding keys prevented the story widgets from incorrectly picking up old state when the list view was rebuilt. To illustrate why you need keys in this situation, I wrote an extremely simple app with two randomly colored widgets that swap places when you tap a button. Here's the code for the app. It consists of a stateful widget, called PositionedTiles, that constructs two stateless tiles, and places them in a row. When I tap the Floating Action button down at the bottom, it swaps their position in the list, as expected. But what happens if we make those colorful tiles stateful instead of stateless, and store the color in the state? Now, when I hit the button, it looks like nothing is changing. But if I add a key to each tile widget, the widgets swap places like you expect. Remember, though, if the entire widget subtree in your collection is stateless, keys aren't needed. Technically, this is all you need to know to use keys in your apps for most simple situations. Now that everyone's left, we can go into how keys work under the covers when Flutter renders these widgets. In the stateless widget version, the row widget has a set of ordered slots for its children. As you've seen in the earlier episodes of the series, for every widget, Flutter builds a corresponding element. The element tree is extremely simple, only holding information about the type of each widget and a reference to children elements. You can think of the element tree like a skeleton of your Flutter app. It shows the structure of your app, but all the additional information can be looked up via reference to the original widget. When we swap the order of the tile widgets in the row, Flutter walks the element tree to see if the skeletal structure is the same. It starts with the row element and then moves to its children. The element tree checks that the new widget is the same type and key as the old one. And if so, it updates its reference to the new widget. In this case, the widgets don't have keys, so Flutter just checks the type. It does the same for the second child. Now, let's run through the same scenario again, only this time with stateful tile widgets. You can see I've got the same widgets and elements as before, but now there are a pair of state objects with them. And the color information is being stored there, not in the widgets themselves. So this time, when I swap the order of the two widgets, Flutter walks the element tree, checks the type of the row widget, and updates the reference. Then, tile element checks that the corresponding widget is the same type-- a tile widget-- and it is. And it does the same for the second child. Flutter uses the element tree and its corresponding state to determine what to actually display on your device. So from our perspective, it looks like your widgets didn't properly swap. In the second version, with the stateful tiles, I added key properties to the widgets. Now if we swap the widgets, the row widgets match like before, but the key of the tile element doesn't match the key of the corresponding tile widget. So Flutter deactivates those elements, moving the references to the tile elements in the element tree, starting with the first one that doesn't match. Then Flutter looks through the non-matched children for an element with the corresponding key. It finds a match, and updates its reference to the corresponding widget. Flutter then does the same thing for the second child. Now, Flutter will display what we expect, with the widgets swapping places and updating their color. So, in summary, keys are useful if you're modifying the order or number of stateful widgets in a collection. For the sake of illustration, I stored the color as state in this example. Often, though, state is much more subtle. Playing animations, displaying data that the user has entered, and scroll location all involve state. So you have a scenario where you need a key for your app. Where do you put it? The answer is to specify a key at the top of the widget subtree that you need to preserve. Since we've been talking about state so much, you might think that it is the first stateful widget. But (SPEAKING WITH STERN MONOTONE) you'd be wrong. To show you why, I wrapped my colorful tile widgets with padding widgets, but I left the keys on the tiles. Now when I click the button, the tiles change to completely different random colors. What's going on? Here's what the widget tree and the element tree look like with the padding widgets added. When we swapped the positions of the children, Flutter's element-to-widget matching algorithm looks at one level of the tree at a time. I grayed out the children's children in the diagram so we can focus on one level at a time. At that first level of children, everything matches up correctly. At the second level, Flutter notices that the key of the tile element doesn't match the key of the widget. So it deactivates that tile element, dropping those connections. The keys we're using in this example are local keys. That means that when matching up widgets to elements, Flutter only looks for a key that matches within a particular level in the tree. Since it can't find a tile element at that level with that key value, it creates a new one, and initializes a new state. In this case, making the widget orange. The same problem happens for the other tile. If we add keys at the level of the padding widgets, Flutter notices the problem, and updates the connections correctly, just like it did in our previous example. Order is restored in the universe. So now you know when to use keys and where to put them. But if you looked at the Flutter documentation, you'll see there are several different kinds of keys. So which one should you use? In the scenario where you're modifying a collection of widgets, like the swapping colored tiles example, you only need to distinguish between the keys of other children. Take a look at the information you're storing in those child widgets to help understand what widget to use. In a to-do list app, we might expect the text of a to-do item to be constant and unique. If that's the case, it's probably a good candidate for a value key, where the text is the value. Now suppose that instead, each child widget stores a more complex combination of data. Perhaps you have an address book app that listed information about each user. Any of the individual fields, like a first name or a birthday, might be the same as another entry, but the combination is unique. In this scenario, an object key is probably most appropriate. If you have multiple widgets in your collection with the same value, or if you want to really ensure that each widget is distinct from all others, you can use the UniqueKey. I used the UniqueKey in the example app because we didn't have any other constant data that we're storing on our tiles, and we don't know what the color will be until we construct the widget. But one thing you don't want to use is a random number in your key. Every time a widget gets built, a new random number will be generated, and you'll lose the consistency between frames. Then you might not as well have used keys in the first place. Page storage keys are specialized keys that store a user's scroll location so the app can preserve it for later. Global keys have two uses. They allow widgets to change parents anywhere in your app without losing state, or they can be used to access information about another widget in a completely different part of the widget tree. An example of the first scenario might be if you want to show the same widget on two different screens, but holding all the same states. You'd want to use a global key. In the second scenario, maybe you want to validate a password, but you don't want to share that state information with other widgets in the tree. Often, though, global keys are a little like global variables. There is usually a better way to look up that state using inherited widgets, or something like redux or the block pattern. So, in summary, use keys when you want to preserve state across widget trees. This most commonly occurs when you're modifying a collection of widgets of the same type, like in a list. Put the key at the top of the widget tree you want preserved, and choose the key type that you're using based on the type of data you're storing in that widget. For more documentation, check out flutter.io. Happy creating. [MUSIC PLAYING]
Info
Channel: Google Developers
Views: 330,264
Rating: 4.8822541 out of 5
Keywords: When to use keys, what are Flutter Keys, Local keys, Global Keys, Fluter Widgets, widget tree, key API, stateful widget, stateless widget, inherited widget, when to use keys, where to put keys in your widget tree, flutter 101, Flutter Widgets 101, interface, Widgets 101, Flutterio, Building flutter app, Flutter apps, ObjectKey, UniqueKey, ValueKey, GlobalKey, LocalKey, flutter tutorial, element tree, flutter developers, GDS: Yes;
Id: kn0EOS-ZiIc
Channel Id: undefined
Length: 9min 40sec (580 seconds)
Published: Mon Nov 26 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.