24

I'm doing the Udacity flutter course. There's this constructor call.

  child: Category(
    name: _categoryName,
    color: _categoryColor,
    iconLocation: _categoryIcon,
  ),

When I did this on my own, I naturally wrote the constructor as follows:

 const Category({
    @required this.name,
    @required this.icon,
    @required this.color
  }) : assert(name != null),
      assert(icon != null),
      assert(color != null);

Disregard the asserts and @requireds. You call using three parameters, so the constructor must have three parameters.

However, in the solution file of this exercise, the instructors did it like this.

  const Category({
    Key key,
    @required this.name,
    @required this.color,
    @required this.iconLocation,
  })  : assert(name != null),
        assert(color != null),
        assert(iconLocation != null),
        super(key: key);

What is this key parameter and why is the parent of the category widget class (StatelessWidget I presume) is being passed it?

I have looked at Key class, but I did not understand anything. There's no context in this page or an example I can use.

MAA
  • 1,294
  • 3
  • 18
  • 34

1 Answers1

43

What are keys?

Let's go through the key documentation you linked..

A Key is an identifier for Widgets, Elements and SemanticsNodes.

Cool, widgets have an identifier, and that's the Key. Easy.

What are keys for?

A new widget will only be used to update an existing element if its key is the same as the key of the current widget associated with the element.

Now this is a bit more cryptic, let's break it down.

What's happening here is when there's a change in state and your widget tree is being rebuilt, flutter needs a way to know:

  • Which widgets are completely new, and need to have a new state created for them;
  • Or most interestingly, which widgets aren't really new, such that flutter already has a state object that should be associated with it. After all this is the reason why widget/state are separate in flutter, so that state survives while views change, animate, rotate, etc.

The key identifies a widget, and this tells flutter whether a widget should be inflated new, or whether it should replace an existing widget in the tree during a build.

Keys must be unique amongst the Elements with the same parent.

Now this becomes obvious, since we can't know which state belongs to this widget if it's key is not unique. Try it yourself! Create a column with two widgets and give them the same key. Spoiler alert: flutter will complain, and you now know why :)

Gotcha, anything else I should know?

For completeness one last point to be made here is about local and global keys. A regular Key is most probably a LocalKey, this one just needs be unique among its siblings. If you want to retain state for a widget that moves around the tree changing parents, then you're looking for a GlobalKey.

Also, flutter uses the type of the object (as in Object.runtimeType) along with the key to identify widgets during a build. This is why you often don't specify a key at all and things still work, because these are likely LocalKeys and you likely don't have two widgets of the same runtimeType under the same parent, so even if they happen to have the same default key they still don't clash.

Edman
  • 5,335
  • 29
  • 32
  • 5
    Tons of text, but in the end it doesn't really explain what it's used for. And in the end the question is just a duplicate of https://stackoverflow.com/questions/50080860/what-are-keys-in-the-stateless-widgets-class/50081052#50081052 – Rémi Rousselet May 19 '18 at 20:21
  • I'm pretty confident this answers what are keys. If you have seen a similar question before, mark the duplicate. – Edman May 19 '18 at 20:28
  • 7
    Yeah but it doesn't answer's OP question `why is the parent of the category widget class (StatelessWidget I presume) is being passed it?`. – Rémi Rousselet May 19 '18 at 20:34