Flutter Redux Navigator GlobalKey.currentState 返回 null [英] Flutter Redux Navigator GlobalKey.currentState returns null

查看:30
本文介绍了Flutter Redux Navigator GlobalKey.currentState 返回 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Redux 开发 Flutter.

I am developing Flutter with Redux.

当用户启动应用程序时,我希望 Redux 自动 dispatch 一个 action.这个动作会让Navigator依赖推送不同的路由.

When a user starts an application, I want Redux to automatically dispatch an action. This action will make the Navigator push different routes dependently.

这个片段 由 Flutter 提供dev 成员使用GlobalKey来使用middleware内的Navigator.

This snippet provided by a Flutter dev member uses the GlobalKey to use the Navigator inside the middleware.

在此之后,我将代码组织如下:

Following this, I organize my code as follows:

ma​​in.dart

void main() {
  final store = new Store(appStateReducer,
      middleware:createRouteMiddleware()
  );
  runApp(new MyApp(store));
}

class MyApp extends StatelessWidget {
  final Store<AppState> store;

  MyApp(this.store);

  @override
  Widget build(BuildContext context) {
    return new StoreProvider<AppState>(
        store: store,
        child: MaterialApp(
            routes: {
              Routes.REGISTER: (context) {
                return RegisterScreenContainer();
              },
              Routes.SET_PROFILE: (context) {
                return SetProfileScreenContainer();
              },
              //Routes.HOME = "/" so this route will be run first
              Routes.HOME: (context) {
                return StoreBuilder<AppState>(
                  //onInit is called to dispatch an action automatically when the application starts. The middleware will catch this and navigate to the appropriate route.
                  onInit: (store) => store.dispatch(
                      ChangeRoute(routeStateType: RouteStateType.Register)),
                  builder: (BuildContext context, Store vm) {
                    return RegisterScreenContainer();
                  },
                );
              },
            }));
  }
}

middleware.dart

Middleware<AppState> createRouteMiddleware(
    {@required GlobalKey<NavigatorState> navigatorKey}) {
  final changeRoute = _createChangeRouteMiddleware(navigatorKey: navigatorKey);
  return TypedMiddleware<AppState, ChangeRoute>(changeRoute);
}

Middleware<AppState> _createChangeRouteMiddleware(
    {@required GlobalKey<NavigatorState> navigatorKey}) {
  print(navigatorKey.currentState);
  return (Store store, action, NextDispatcher next) async {
    switch ((action.routeStateType as RouteStateType)) {
      case RouteStateType.Home:
        navigatorKey.currentState.pushNamed(Routes.HOME);
        break;
      case RouteStateType.Register:
        //The middleware intercepts and push the appropriate route depending on the action
        navigatorKey.currentState.pushNamed(Routes.REGISTER);
        break;
      default:
        break;
    }
    next(action);
  };
}

这是我得到的错误

[ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] 未处理的异常:E/flutter(2544):NoSuchMethodError:在 null 上调用了方法pushNamed".E/颤振(2544):接收器:空E/flutter (2544):尝试调用:pushNamed("/register")

这意味着action被成功调度,但是navigatorKeycurrentStatenull.

This means that the action was successfully dispatched, however, the currentState of the navigatorKey was null.

我在这里遗漏了什么?

请注意,我知道 这个看似相似的问题 并不真正适用于我的问题.即使我将 ma​​in.dartmiddleware.dart 合并到一个文件中,它仍然不起作用.

Note that I am aware of this seemingly similar question which does not really apply to my question. Even when I merge the main.dart and middleware.dart into one file, it still doesn't work.

推荐答案

我通过将全局导航键放在单独的文件中解决了这个问题.然后我在我的 materialApp 和中间件中使用了它.

I solved this issue by having the global navigator key in a separate file. Then I used that in my materialApp and in the middleware.

我将导航键放在我的 keys.dart 文件中:

I put the navigator key in my keys.dart file:

import 'package:flutter/widgets.dart';
class NoomiKeys {
  static final navKey = new GlobalKey<NavigatorState>();
}

为 MaterialApp 小部件添加了密钥navigatorKey: NoomiKeys.navKey",在我的 main.dart 文件中(删除了大量代码以使其更快阅读):

Added the key to MaterialApp widget "navigatorKey: NoomiKeys.navKey," in my main.dart file (alot of code is removed to make it faster to read):

import 'package:noomi_nursing_home_app/keys.dart';


@override
Widget build(BuildContext context) {
return StoreProvider<AppState>(
  store: store,
  child: MaterialApp(

    //Add the key to your materialApp widget
    navigatorKey: NoomiKeys.navKey,

    localizationsDelegates: [NoomiLocalizationsDelegate()],
    onGenerateRoute: (RouteSettings settings) {
      switch (settings.name) {

并在navigate_middleware.dart中使用它;

And use it in navigate_middleware.dart;

import 'package:noomi_nursing_home_app/actions/actions.dart';
import 'package:noomi_nursing_home_app/keys.dart';
import 'package:redux/redux.dart';
import 'package:noomi_nursing_home_app/models/models.dart';

List<Middleware<AppState>> navigateMiddleware() {

  final navigatorKey = NoomiKeys.navKey;
  
  final navigatePushNamed = _navigatePushNamed(navigatorKey);
  return ([
    TypedMiddleware<AppState, NavigatePushNamedAction>(navigatePushNamed),
  ]);
}

Middleware<AppState> _navigatePushNamed(navigatorKey) {
  return (Store<AppState> store, action, NextDispatcher next) {
    next(action);
    navigatorKey.currentState.pushNamed(action.to);
  };
}

这篇关于Flutter Redux Navigator GlobalKey.currentState 返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆