Open joshuadutton opened 4 months ago
Could you explain what are you trying to do and why it's not working? It's hard to understand.
Could you explain what are you trying to do and why it's not working? It's hard to understand.
I'm not looking for help to get something working. Everything is working fine. This is a suggestion for a different approach that I want to discuss. If it's confusing, I could provide a complete example as a PR.
It's confusing. Can you describe it by words, it's better than some code.
@XuanTung95 are you familiar with Inherited Widgets? It's built into the Flutter framework as a way to propagate information to widgets in the widget tree. (See https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html). In fact, it's what GoRouter uses to allow you to get the router with the build context when you write final router = GoRouter.of(context);
. I find the name, Inherited Widget, confusing because it's not referring to object inheritance, like subclassing a Widget.
Using an Inherited Widget, I can pass my auth state directly to the redirect
method of my router, bypassing the need to wrap my router in a Riverpod provider. Inside the redirect
method, I just need to call final authUser = Auth.of(context);
, I feel like this is much cleaner since it leverages the Flutter APIs instead of working around them.
To do this, I just have the Inherited Widget watch my Riverpod auth provider and then rebuild it's child widgets whenever the auth state changes. From what I understand, the Flutter framework is smart in doing so, only rebuilding the widgets that actually reference the .of(context)
method.
.of(context)
= service locator + dependence.
It rebuild because of the "dependence" part. You can use only the service locator without "dependence".
There are many ways to do it, for example: context.getInheritedWidgetOfExactType()
, 'ref.read', 'ProviderScope.containerOf(context, listen: false).read()'
I don't think using InheritedWidget is user friendly. Why don't you use riverpod instead, it do the same thing. If that is the suggestion you are looking for.
I want feedback on this approach. I wasn't satisfied with anything I've seen with making a router provider and all the extra stuff required to make that work well. Since the redirect method takes a
BuildContext
, I wanted to see what it would take to implementAuth.of(context)
while also working with Riverpod. Here's what I did:Auth Widget and InheritedWidget example:
Then I just wrap my app with
Auth
like this:A big upside to this approach is that whenever my
authUser
changes, the InheritedWidget causes it's children that are usingAuth.of(context)
to rebuild. This includes the router! That means that redirects are automatically triggered by changing auth state. I've done some testing, and this only happens when I expect it to.Any downsides?
I could provide a complete example of this approach. I've also setup my app and boilerplate to use
StatefulShellRoute
s and swappable Firebase auth, which are two other things this example intends to provide (looking at the other issues).