-
Notifications
You must be signed in to change notification settings - Fork 215
best way to handle navigation from a reducer? #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
FYI you can access your app's Navigator without a /// A key to use when building the [Navigator].
///
/// If a [navigatorKey] is specified, the [Navigator] can be directly
/// manipulated without first obtaining it from a [BuildContext] via
/// [Navigator.of]: from the [navigatorKey], use the [GlobalKey.currentState]
/// getter.
///
/// If this is changed, a new [Navigator] will be created, losing all the
/// application state in the process; in that case, the [navigatorObservers]
/// must also be changed, since the previous observers will be attached to the
/// previous navigator.
final GlobalKey<NavigatorState> navigatorKey; Create the key: final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>(); Pass it to MaterialApp: new MaterialApp(
title: 'MyApp',
onGenerateRoute: generateRoute,
navigatorKey: key,
); Push routes: navigatorKey.currentState.pushNamed('/someRoute'); |
I find it preferable to use this to navigate in a side-effect action/middleware and leave navigation state handling to flutter. |
ah, awesome! Totally didn't look deeper at the navigation API one bit. HUGE thanks, that at the very least unblocks me! Is there any documentation on how to write a middleware? That's another thing I didn't see. Middleware does indeed seems like the right place for this. |
Thanks for writing in and to xqwzts for the good answer! On vacation for a few more days, but you can find some docs on Middleware here: https://github.com/johnpryan/redux.dart/blob/master/doc/async.md |
I guess there's no reason to leave this open. Thanks for the help, everyone! |
If anyone is still reading this -- I am trying this but it's not working all that well -- when I get an outside event .. and want to go to a particular screen .. it goes there -- but loses ALL context such as theme / backbitten / app bar stuff / etc. It's a plain screen and no way to navigate .. This is an existing screen that is navigable via App Bar buttons, etc. So ... how can this work? Cheers |
it would be nice if you also showed how did you get reference to navigatorKey in |
@temirfe You have two options:
In code using a class MyMiddleware extends MiddlewareClass<AppState> {
final GlobalKey<NavigatorState> navigatorKey;
MyMiddleware(this.navigatorKey);
@override
void call(Store<AppState> store, dynamic action, NextDispatcher next) {
if (action is SomeAction) {
navigatorKey.currentState.pushNamed('/someRoute');
}
}
} To provide this to your Store: void main() {
final navigatorKey = new GlobalKey<NavigatorState>();
final store = Store(myReducer, middleware: [MyMiddleware(navigatorKey)]);
runApp(StoreProvider(store: store, child: MaterialApp(navigatorKey: navigatorKey)));
} |
I have a
Ticker
streaming events to my store, each of which does some tiny math. At a certain threshold, the app should navigate.It is mildly complicated to find this event, so I could detect this case and do this within the
Ticker
-- though even then, that's kinda gross as I need acontext
and I don't actually know how safe it is to just navigate with the last context passed intobuild()
(since theTicker
is inherently firing outside the build method and such).I then figured it'd be better if I have a singleton Stream that can exchange this data. I'm not entirely sure how safe it is in the context of hot reload and such, if I should be pushing out from one Store into a Stream which affects the app elsewhere...but, I figure, that's a small enough concern I may as well do this to unblock me.
I realized that I have the same problem of getting the context -- I could use a StreamBuilder, but that would always, on each build, get me the most recent navigation pushed to my stream. Not what I want. And if I don't use StreamBuilder, I'm not a builder, and so I don't have a context to go off of.
I'm not convinced this shouldn't be a middleware, but they don't seem well documented. I think navigation is often done in a middleware with react/redux, but don't actually follow the code examples well, and they lean heavily on the navigation APIs itself which are different on the web.
I'm starting to realize, anyways, that Navigator is probably basically just altering the state of the
MaterialApp
by probably looking up some kind ofInheritedNavigationWidget
or somethingSo this makes me think I shouldn't be navigating at all, but that my reducer should set
page = Pages.Histogram
in my state, and then myMyApp
component can do all routing with that. Downside here is that I have to reimplement things like push/pop/replace.Is this a solved problem, am I on the right track that I should just reimplement navigation in redux because navigation is just a form of state management anyway built through less testable techniques?
The text was updated successfully, but these errors were encountered: