Why you should not use Navigation 2.0 with Flutter?

Денис Богатырев
5 min readApr 5, 2021

This article compares flutter’s Navigation 1.0 and 2.0 and describes cases where newer approach is over complicated or not needed at all. We’ll go through simple app using both approaches. This is review article and did not meant to compromise new declarative approach, it purposed to show challenges that developer may face during app development. If you want to know more about Navigation 1.0 or 2.0 consider reading this article.

Input variables:

Let’s discuss what will be in our sample app. We will have, a list of users, provided by Random user API. There will not be api call implementation, data is hardcoded for demo purposes. UsersScreen will show ListView of users, on user tap UserScreen will be opened with information about user and a list of “friends”which also can be tapped on and go to UserScreen with different user. All of users “fetching” and filtering will be hidden in UsersService class.

Navigation 1.0

Finally we can start writing some code. Let’s start with something simple and known Navigation 1.0. If you’re used Flutter for some time you should be familiar with such concepts as:

  • Navigator — a widget that manages a stack of Route objects.
  • Route — an object managed by a Navigator that represents a screen, typically implemented by classes like MaterialPageRoute.

I’m used to Anonymous routes approach, when you push route directly, but it can be easily translated to named routes.

How do we handle simple navigation from UsersScreen to UserScreen? We need to use Navigator obviously. Something like this:

I prefer to simplify this by creating static methods on each screen with required params and settings:

Good side of this approach, from my point of view of course, is that route creation is tied up with screen declaration and most important you don’t have to deal with named route arguments and type casting, just pass what you need directly to screen.

And thats it, pop is handled by OS (back button on Android and swipe on iOS), you can push as many screens as you want.

Navigation 2.0

NOTE: I will not deep dive in configuration of Navigation 2.0, if you want to learn how to use it look into this article.

Path class

First thing that you will have to deal with using Navigation 2.0 is describing your application routing state/path class. This class is basically deserialized URL string. In our case we have 2 cases to deal with:

  1. You just opened application, so you will be seeing list of all users UsersScreen.
  2. You tapped on user tile and being navigated to user details UserScreen.

“Speaking” in code we will need to store selected user and if its null list of users will be shown. Here is code:

Information parser

Second thing that you’ll need is information parser. This class describes how your path class will be transformed into URL and vice versa. If you are familiar with web development it will be very easy to understand.

Router delegate

Router delegate is center point of Navigation 2.0. It defines what pages will be rendered depending on your path. Also you can override page transitions or back button logic.

Let’s quickly go through the important stuff:

  • get currentConfiguration — returns current path depending on local state
  • setNewRoutePath — allows you to update your state if path was manually changed (e.g. edit browser url)
  • build — here you build your navigator and stack of pages depending on your local state

Last steps

After you created three previous class it’s time to wire application with our new router:

After that you are ready to go.

Pros and Cons

Let’s have a look on what have been done in both approaches and try to understand strong and weak points of each one.

Navigation 1.0

Most noticeable point about this approach is amount of code required to get it work. And less code brings us second point: ease to understand and use. Just call Navigator.of(context) and you ready to push, pop, replace etc. You can easily setup navigation of your application and focus on more important stuff like business logic, domain or UI.

But it comes with cost of handling multiple routes at same time. For example you have Deep Links in your app or Push Notifications, in those scenarios you may need to push several routes at same moment (UsersScreen -> UserScreen) to keep user experience consistent, so when they hit back they will end up where they expect. Also with anonymous routes (with my kind of approach) you may experience some issues with web.

Navigation 2.0

Unlike it’s previous version, Navigation 2.0 is very complex, at least for the first time. It requires more lines of code to be written, 120 in 2.0 vs 30 in 1.0 for this simple 2 page application. This complexity brings lots of points and cases to keep in mind

  • Navigation between screens. Instead of “pushing” or “navigating” to screen you need change your delegate class state so it can build different pages.
  • You will need to pass delegate through context so it can be accessible from your widgets. Something like provider would be very helpful.
  • If you look closely, you will see that we only storing one user so as soon as user navigates back he will notice that there is no history left. So history need to be developed from scratch. And as much complexity of you app grows your history implementation will grow too.
  • Complexity of your history will increase, amount of cases to check will increase too. You may end up with hundreds of if conditions in build, onPopPage and setNewConfiguration methods. Same applies to RouteInformationParser.
  • Order of pages matters, so as order of condition checking for pages. Another point for developer to not miss.

And in the end bright side of Navigation 2.0 is that you can handle any case of multiple screen interaction, supporting web is much easier and you can override and/or wrap your routes in anything you want.

Conclusion

NOTE: wanted to say that everything above is my personal observation and opinion and you are free to use whatever you want. 1.0 is still supported and 2.0 was designed as alternative not replacement.

Navigation 2.0 is more complex and hard to understand concept that requires changes. Seriously there even was an issue to make it more simpler. Amount of things to keep in mind and handle is enormous. And all of it just to be able to work with multiple routes and support web.

My suggestion is to use Navigator 2.0 if web is one of your target platforms, but still you may want to try using navigation libraries such as fluro.

All code used in this article can be found in this repo.

Thank you for reading and have a nice day :)

--

--