Repository: flutter
Issue: [go_router] Error thrown when try to switch route config while preserving widget state
Labels: package,has reproducible steps,P2,p: go_router,team-go_router,triaged-go_router,found in release: 3.16,found in release: 3.19

### Steps to reproduce

I would like to preserve the state of widgets, i.e. the text editing controller, so I added a global key to `ScreenA`.

1. Run the code sample
2. Click the "Switch route map" button
3. Observe the console

I know I can refactor the `TextEditingController` in this example. However, it is not practical to refactor all kinds of states out of the widgets, which would make `StatefulWidget` pointless.

### Expected results

No error is thrown while the text entered to the text field is preserved.

### Actual results

The following error is thrown:

```
The following assertion was thrown while finalizing the
widget tree:
Duplicate GlobalKey detected in widget tree.
The following GlobalKey was specified multiple times in
the widget tree. This will lead to parts of
the widget tree being truncated unexpectedly, because the
second time a key is seen, the previous
instance is moved to the new location. The key was:
- [GlobalKey#a4274]
This was determined by noticing that after the widget with
the above global key was moved out of its
previous parent, that previous parent never updated during
this frame, meaning that it either did
not update at all or updated before the widget was moved,
in either case implying that it still
thinks that it should have a child with that global key.
The specific parent that did not update after having one
or more children forcibly removed due to
GlobalKey reparenting is:
- Builder
A GlobalKey can only be specified on one widget at a time
in the widget tree.
```

### Code sample

<details open><summary>Code sample</summary>

```dart
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() {
  runApp(const MyApp());
}

final key = GlobalKey();

final configA = RoutingConfig(
  routes: [
    GoRoute(
      path: '/a',
      builder: (context, state) => ScreenA(key: key),
    ),
    GoRoute(
      path: '/b',
      builder: (context, state) => const ScreenB(),
    ),
  ],
);

final configB = RoutingConfig(
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('With shell route'),
          ),
          body: child,
        );
      },
      routes: [
        GoRoute(
          path: '/a',
          builder: (context, state) => ScreenA(key: key),
        ),
        GoRoute(
          path: '/b',
          builder: (context, state) => const ScreenB(),
        ),
      ],
    ),
  ],
);

final configNotifier = ValueNotifier(configA);

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: GoRouter.routingConfig(
        initialLocation: '/a',
        routingConfig: configNotifier,
      ),
    );
  }
}

class ScreenA extends StatefulWidget {
  const ScreenA({super.key});

  @override
  State<ScreenA> createState() => _ScreenAState();
}

class _ScreenAState extends State<ScreenA> {
  final TextEditingController _textController = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          TextField(
            controller: _textController,
          ),
          const SizedBox(height: 5.0),
          TextButton(
            onPressed: () {
              configNotifier.value = configB;
            },
            child: const Text(
              'Switch route map',
            ),
          ),
        ],
      ),
    );
  }
}

class ScreenB extends StatelessWidget {
  const ScreenB({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text(
          'Screen B',
        ),
      ),
    );
  }
}
```

</details>


### Screenshots or Video

<details open>
<summary>Screenshots / Video demonstration</summary>

[Upload media here]

</details>


### Logs

<details open><summary>Logs</summary>

```console
[Paste your logs here]
```

</details>


### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
Doctor summary (to see all details, run flutter doctor
-v):
[✓] Flutter (Channel stable, 3.16.7, on macOS 14.3 23D56
    darwin-arm64, locale zh-HK)
[✓] Android toolchain - develop for Android devices
    (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.85.2)
[✓] Connected device (2 available)
[✓] Network resources

• No issues found!
```

</details>