DIVING INTO KEYS IN FLUTTER
Using Keys in Flutter
If you are unaware of some terms like ValueKey, UniqueKey, ObjectKey etc then you on the right article.
A Key is an identifier for Widgets, Elements and SemanticsNodes.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.
Let’s understand the use of keys in flutter with the help of an example.
Suppose we have two simple TextFields (wrapped as a stateful widget named MyTextField) in a Column and let’s say you hide the first of two on FAB(Floating Action Button) press. The first one should hide and second one should take its place
So in this code we have MyTextField as a simple stateful widget having TextField with its Text Controller as a field variable:
The Home page simply contains a Column having two of these MyTextField as its children. The first one has a display condition which is controlled by FAB press action.
If you run this code. The result looks something like this:
On Pressing FAB we can see ONLY the first one retains not the second one , which is completely opposite to what we are trying to achieve.
The issue here is on FAB press the widget tree is rebuild and because of rebuild MyTextField is rebuild and hence the state of second is lost.
A brief explanation can be given as the flutter on rebuild tries to compare the element tree before and after and since we removed one element(without key/tag) the flutter assumes to remove second instead of first.
Here’s where the role of KEY comes in picture. We’ll discuss only three types of keys ValueKey, ObjectKey, UniqueKey.
Let’s look at the documentation of ValueKey:
A key that uses a value of a particular type to identify itself.A ValueKey<T> is equal to another ValueKey<T> if, and only if, their values are operator==.This class can be subclassed to create value keys that will not be equal to other value keys that happen to use the same value. If the subclass is private, this results in a value key type that cannot collide with keys from other sources, which could be useful, for example, if the keys are being used as fallbacks in the same scope as keys supplied from another widget.
This basically says if the parameter passed inside ValueKey() is same on rebuilding then the widget will not rebuild because flutter now knows this widget has a tag.
Let’s now pass ValueKey in our MyTextFields like this:
if (showFirst) MyTextField(key: ValueKey(1),),
Here we can see ValueKey takes a parameter which we have set to an integer 1, 2. We are free to choose anything as parameter just it shouldn’t change on rebuilding.
If you run these changes, the result looks something like this:
Great!!! It works as expected. ValueKey worked ❤️
Similar to ValueKey is ObjectKey. ObjectKey is used when you have complex data and you have to use an object itself. Read more about ObjectKey here.
Remember not to pass same parameter again to some other widget. Flutter will throw exception ‘Duplicate Keys Found’.
No two widgets can have same keys in widget tree.
Let’s see what’s UniqueKey:
A key that is only equal to itself.
As the name suggests a UniqueKey is unique every-time on rebuild.
Now let’s pass UniqueKey() instead of ValueKey() and see what happens:
Here you can see even the filled text has been erased. This is because the entire states of both the widgets are lost and are newly created on rebuilding.
Hence unique keys must be used only in stateless widgets where the widgets aren’t depended on internal data change.
Sample code is available: https://github.com/apgapg/flutter_sample_key (Don’t forget to ⭐⭐⭐)
Whola! Both you and I learnt something new today. Congrats
Clap! Clap! Clap!