csells / go_router

The purpose of the go_router for Flutter is to use declarative routes to reduce complexity, regardless of the platform you're targeting (mobile, web, desktop), handling deep linking from Android, iOS and the web while still allowing an easy-to-use developer experience.
https://gorouter.dev
441 stars 96 forks source link

go/goNamed rebuilds the current widget before navigate #163

Closed fpabl0 closed 2 years ago

fpabl0 commented 2 years ago

Hello, I am refactoring my apps to use this amazing router (thanks for this wonderful work ^_^). However, I noticed that when context.go/context.goNamed is called, the caller widget is rebuilt before navigates to the other page. I don't know if this behavior is expected or not, but using Navigator.push/Navigator.pushNamed does not happen this.

I am using this code:

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);

  @override
  Widget build(BuildContext context) => MaterialApp.router(
        routeInformationParser: _router.routeInformationParser,
        routerDelegate: _router.routerDelegate,
        title: 'GoRouter Example: Initial Location',
      );

  final _router = GoRouter(
    initialLocation: '/',
    routes: [
      GoRoute(
        name: "home",
        path: '/',
        pageBuilder: (context, state) => MaterialPage<void>(
          key: state.pageKey,
          child: const MyPage(
            title: "home",
            goTo: "second",
          ),
        ),
      ),
      GoRoute(
        name: "second",
        path: '/page2',
        pageBuilder: (context, state) => MaterialPage<void>(
          key: state.pageKey,
          child: const MyPage(
            title: "second",
            goTo: "home",
          ),
        ),
      ),
    ],
    errorPageBuilder: (context, state) => MaterialPage<void>(
      key: state.pageKey,
      child: const MyPage(
        title: "error",
        goTo: "home",
      ),
    ),
  );
}

class MyPage extends StatelessWidget {
  const MyPage({
    required this.title,
    required this.goTo,
  });

  final String title;
  final String goTo;

  @override
  Widget build(BuildContext context) {
    print("rebuild Page $title");
    return Scaffold(
      appBar: AppBar(
        title: Text("Page $title"),
      ),
      body: Center(
        child: TextButton(
          child: Text("Go to $goTo"),
          onPressed: () {
            context.goNamed(goTo);
          },
        ),
      ),
    );
  }
}

When you navigate from Home page to the Second Page, then "rebuild Page home" is printed showing that the Home Page is rebuilt while calling context.goNamed.

csells commented 2 years ago

I believe I have my updateShouldNotify implementation incorrect.

csells commented 2 years ago

should be fixed in v2.2.7. @fpabl0 can you verify?

fpabl0 commented 2 years ago

Yes, it works :). Thank you so much!