Finally, let’s talk about good practices:

Keep inherited widgets small

Overloading them with a lot of context ends up costing you the 2nd and 3rd advantage mentioned above since Flutter cannot detect which part of the context is updated and which part the widgets are using. Instead of:

Prefer doing:

Use const to build your widgets

Without const, selective rebuilding of the sub-tree does not happen. Flutter creates a new instance of each widget in the sub-tree and calls build() wasting precious cycles especially if your build methods are heavy.

Properly scope your inherited widgets

Inherited widgets are placed at the root of a widget tree. That, in effect, becomes their scope. In our team, we found that the power to declare context anywhere in the widget tree is a bit too much. So, we restrict our context widgets to accept only Scaffold (or its derivatives) as a child. That way, we ensure the most granular context can be at the page level ending up with two types of scope:

App-scoped widgets such as MediaQuery . These are accessible by any widget on any page in your app since they sit at the root of your app widget tree.

. These are accessible by any widget on any page in your app since they sit at the root of your app widget tree. Page-scoped widgets such as the MyInheritedWidget in the example above.

You should choose one or the other depending on where the context is applicable.

Page-scoped widgets cannot cross route boundary

This one seems like a no-brainer. However, it has profound implications because most apps have more than one levels of navigation. This is what your app could look like:

This is what Flutter sees:

From Flutter’s perspective, a navigation hierarchy does not exist. Each page (or scaffold) is a widget tree tied to the application widget. Therefore, when you use Navigator.push to display these pages, they do not inherit the widget carrying parent’s context. In the example above, you will need to pass the Student context from Student page to Student Bio page explicitly.

Although there are different ways to pass context, I suggest parameterizing your routes the old-fashioned way (such as URL style encoding if you use named routes). This also ensures the pages can be constructed solely from the route without needing the context from their parent page.

Happy coding!