Search code examples
flutterdartflutter-navigationflutter-go-router

Proper way of using a splashscreen with `go_router` package


I display a splash screen when the user open the app and in the meantime the it loads some data. When it finish I want to show a page based on that data. What is the proper way of doing this with the go_router package? The code below is more or less what I'm trying to do:

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  final GoRouter _router = GoRouter(
    initialLocation: '/',
    routes: <RouteBase>[
      GoRoute(
        path: '/',
        builder: (context, state) => const SplashScreen(),
      ),
      GoRoute(
        path: '/a',
        builder: (context, state) => const ScreenA(),
      )
    ],
  );

  @override
  Widget build(BuildContext context) =>
      MaterialApp.router(routerConfig: _router);
}

class SplashScreen extends StatelessWidget {
  const SplashScreen({super.key});

  @override
  Widget build(BuildContext context) {
    Future.delayed(const Duration(seconds: 1))
        .then((value) => GoRouter.of(context).go('/a')); // !!!
    return const Center(child: FlutterLogo());
  }
}

class ScreenA extends StatelessWidget {
  const ScreenA({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('Screen A'),
      ),
    );
  }
}

The code works as expected but I get error messages:

Error: Looking up a deactivated widget's ancestor is unsafe.
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dar
t 266:49  throw_
packages/flutter/src/widgets/framework.dart 4241:9
<fn>
packages/flutter/src/widgets/framework.dart 4254:14
[_debugCheckStateIsActiveForAncestorLookup]
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 557:7                                     [_complete]
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future.dart 421:15                                         <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19       internalCallback

What's wrong? How can I fix this?


Solution

  • To fix it create a key at the top of the file

    final GlobalKey<NavigatorState> _rootNavigatorKey =
        GlobalKey<NavigatorState>(debugLabel: 'root');
    

    and add it as key in the root path of your _router definition:

    navigatorKey: _rootNavigatorKey,
    

    then replace

    GoRouter.of(context).go('/a')
    

    with

    GoRouter.of(_rootNavigatorKey.currentContext!).go('/a'))