The-ring-io / flutter_phoenix

Easily restart your application from scratch.
MIT License
153 stars 15 forks source link

Doesn't work with go_router #28

Open chris-rutkowski opened 1 year ago

chris-rutkowski commented 1 year ago

Hello, go_router is very popular package, now maintained by the Flutter team.

Unfortunately, Phoenix doesn't work as expected with it, you can verify with the attached source code. Most likely it is not directly related to go_router, but the underlying Navigator 2.0 (with URL for navigation).

I left the print statements to understand what happens when I call the rebirth method. The app is rebuilt, stateful Detail page is rebuilt, unfortunately, the state of the Detail page is not recreated. The very same example with imperative navigator works just fine with Phoenix.

You can see the journey I see in the console:

# run app
MyApp build
Home build
# click Go to detail
Detail init
Detail build
Home build
# click the increment button twice
Detail build
Detail build
# click rebirth
MyApp build
Detail build
Home build
# no Detail init, the increment counter stays at 2, not 0

I would appreciate your advice on how this could be resolved. I'm using Flutter stable 3.3.5 and confirmed the same issue with the most recent, go_router 6.0.0 (most recent) and flutter_phoenix 1.1.0 (most recent).

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

final _router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const Home(),
      routes: [
        GoRoute(
          path: 'detail',
          builder: (context, state) => const Detail(),
        ),
      ],
    ),
  ],
);

void main() {
  runApp(
    Phoenix(child: const MyApp()),
  );
}

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

  @override
  Widget build(BuildContext context) {
    debugPrint('MyApp build');
    return MaterialApp.router(
      routerConfig: _router,
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    debugPrint('Home build');
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: Center(
        child: TextButton(
          onPressed: () => context.go('/detail'),
          child: const Text('Go to detail'),
        ),
      ),
    );
  }
}

class Detail extends StatefulWidget {
  const Detail({Key? key}) : super(key: key);

  @override
  State<Detail> createState() => _DetailState();
}

class _DetailState extends State<Detail> {
  int _counter = 0;

  @override
  void initState() {
    debugPrint('Detail init');
    super.initState();
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    debugPrint('Detail build');
    return Scaffold(
      appBar: AppBar(title: const Text('Detail')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('$_counter'),
            TextButton(
              onPressed: () => Phoenix.rebirth(context),
              child: const Text('rebirth'),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        child: const Icon(Icons.add),
      ),
    );
  }
}

Kind regards

Miiite commented 1 year ago

That's a pretty old issue, but du you still face the problem ? We use the phoenix package on an internal project, while also using the go_router package, and we didn't encounter any specific behavior issue

joshipucher commented 9 months ago

I had the same issues and figured out that Phoenix doesn't work with go_router if you are not on the root screen. Anyway, if you do Navigator.of(context).pop(); before restarting with phoenix, I also got an error.

My solution was to add this line before Phoenix.rebirth(context); context.go('/'); Phoenix.rebirth(context);