diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index df331c32997..00c63880d8c 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.5.7 + +- Fixes a bug that go_router would crash if `GoRoute.pageBuilder` depends on `InheritedWidget`s. + ## 6.5.6 - Fixes an issue where ShellRoute routes were not logged when debugLogDiagnostic was enabled. diff --git a/packages/go_router/lib/src/builder.dart b/packages/go_router/lib/src/builder.dart index 72d0574eb91..681f1d2ec44 100644 --- a/packages/go_router/lib/src/builder.dart +++ b/packages/go_router/lib/src/builder.dart @@ -74,7 +74,6 @@ class RouteBuilder { PopPageCallback onPopPage, bool routerNeglect, ) { - _routeMatchLookUp.clear(); if (matchList.isEmpty) { // The build method can be called before async redirect finishes. Build a // empty box until then. @@ -139,7 +138,7 @@ class RouteBuilder { final Map, List>> keyToPage = , List>>{}; try { - assert(_routeMatchLookUp.isEmpty); + _routeMatchLookUp.clear(); _buildRecursive(context, matchList, 0, onPopPage, routerNeglect, keyToPage, navigatorKey, registry); diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 5c08a6a13c8..1bd627951aa 100644 --- a/packages/go_router/pubspec.yaml +++ b/packages/go_router/pubspec.yaml @@ -1,7 +1,7 @@ name: go_router description: A declarative router for Flutter based on Navigation 2 supporting deep linking, data-driven routes and more -version: 6.5.6 +version: 6.5.7 repository: https://github.com/flutter/packages/tree/main/packages/go_router issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22 diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index fd19fa3539e..81df210f4ba 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -844,6 +844,42 @@ void main() { }); }); + testWidgets('does not crash when inherited widget changes', + (WidgetTester tester) async { + final ValueNotifier notifier = ValueNotifier('initial'); + final List routes = [ + GoRoute( + path: '/', + pageBuilder: (BuildContext context, GoRouterState state) { + final String value = context + .dependOnInheritedWidgetOfExactType()! + .notifier! + .value; + return MaterialPage( + key: state.pageKey, + child: Text(value), + ); + }), + ]; + final GoRouter router = GoRouter( + routes: routes, + ); + await tester.pumpWidget( + MaterialApp.router( + routerConfig: router, + builder: (BuildContext context, Widget? child) { + return TestInheritedNotifier(notifier: notifier, child: child!); + }, + ), + ); + + expect(find.text(notifier.value), findsOneWidget); + + notifier.value = 'updated'; + await tester.pump(); + expect(find.text(notifier.value), findsOneWidget); + }); + testWidgets( 'Handles the Android back button when a second Shell has a GoRoute with parentNavigator key', (WidgetTester tester) async { @@ -3480,6 +3516,14 @@ void main() { }); } +class TestInheritedNotifier extends InheritedNotifier> { + const TestInheritedNotifier({ + super.key, + required super.notifier, + required super.child, + }); +} + /// This allows a value of type T or T? to be treated as a value of type T?. /// /// We use this so that APIs that have become non-nullable can still be used