How to use `GlobalKey` to maintain widgets’ states when changing parents?

The most common use-case of using GlobalKey to move a widget around the tree is when conditionally wrapping a “child” into another widget like so:

Widget build(context) {
  if (foo) {
    return Foo(child: child);
  }
  return child;
}

With such code, you’ll quickly notice that if child is stateful, toggling foo will make child lose its state, which is usually unexpected.

To solve this, we’d make our widget stateful, create a GlobalKey, and wrap child into a KeyedSubtree.

Here’s an example:

class Example extends StatefulWidget {
  const Example({Key key, this.foo, this.child}) : super(key: key);

  final Widget child;
  final bool foo;

  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  final key = GlobalKey();

  @override
  Widget build(BuildContext context) {
    final child = KeyedSubtree(key: key, child: widget.child);

    if (widget.foo) {
      return Foo(child: child);
    }
    return child;
  }
}

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)