【问题标题】:Flutter Redux Navigator GlobalKey.currentState returns nullFlutter Redux Navigator GlobalKey.currentState 返回 null
【发布时间】:2018-05-12 06:18:08
【问题描述】:

我正在使用 Redux 开发 Flutter。

当用户启动应用程序时,我希望 Redux 自动 dispatchaction。此操作将使Navigator 依赖推送不同的路由。

这个sn-p provided by a Flutter dev member 使用GlobalKeymiddleware 中使用Navigator

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

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)] Unhandled exception: E/flutter ( 2544): NoSuchMethodError: The method 'pushNamed' was called on null. E/flutter ( 2544): Receiver: null E/flutter ( 2544): Tried calling: pushNamed("/register")

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

我在这里错过了什么?

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

【问题讨论】:

    标签: redux flutter redux-middleware


    【解决方案1】:

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

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

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

    在我的 main.dart 文件中添加了 MaterialApp 小部件“navigatorKey: NoomiKeys.navKey”的键(删除了很​​多代码以加快阅读速度):

    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 中使用;

    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);
      };
    }
    

    【讨论】:

      【解决方案2】:

      您好像忘记声明并将 navigatorKey 传递给中间件

      final navigatorKey = GlobalKey<NavigatorState>();
      void main() {
        final store = Store(appStateReducer,
            middleware:createRouteMiddleware(navigatorKey: navigatorKey)
        );
        runApp(MyApp(store));
      }
      

      而且您的 MaterialApp 也缺少 navigatorKey

      MaterialApp(
        navigatorKey: navigatorKey
        routes: /* your routes */
      )
      

      【讨论】:

        猜你喜欢
        • 2020-08-23
        • 2021-09-28
        • 2020-11-10
        • 2020-07-12
        • 2021-06-14
        • 2021-04-19
        • 2021-06-29
        • 2020-12-29
        • 2019-11-22
        相关资源
        最近更新 更多