使用路由器直接导航而不是在异步回调中使用上下文?

问题描述 投票:0回答:1

这是我的项目的构建方式:

我有一个 router.dart 文件,用于管理路由

class MainRouter {

GoRouter router = GoRouter {
//...
}
}

我将此 GoRouter 对象传递到我的 MaterialApp.router-Widget 中:

class MyApp extends StatelessWidget {
  MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
routerConfig: MainRouter.router
//..
)
}

我将 BuildContext 作为我的 AppEvent 的属性。

class AppEvent extends Equatable {
  final BuildContext context;

  const AppEvent(this.context);

  @override
  List<Object> get props => [context];
}

现在,我的 AppBloc 中有一个异步回调函数,我需要先从数据库中删除某些内容,然后导航到主屏幕。

 void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
    
    await _deleteDatabase();

    event.context.go("/home");
  }

问题是,我在项目中遇到以下 lint 问题:“不要跨异步间隙使用‘BuildContext’s。”

我知道,根据这个问题,我可以用

event.context.mounted
检查以确保BuildContext已安装,但我仍然有那个lint问题。

我尝试直接访问

MainRouter.router
并调用
MainRouter.router.go("/home")
并且成功了,但这会违反 GoRouter 或 Bloc 架构的任何架构规则吗?

感谢您的见解!

flutter dart architecture bloc gorouter
1个回答
0
投票

选项1

您可以使用 BlocConsumer 来监听特定的 BLoC 状态,这是一个定义的状态,指示您应该转到该路线。

class AppPopState extends AppState {
  const AppPopState()
}

然后在您的 BLoC 返回该状态:

 void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
    
    await _deleteDatabase();

    emit(const AppPopState());
  }

在小部件中监听该状态:

Widget build(context) {
 return BlocConsumer(
   listenWhen: (_, state) => state is AppPopState,
   listener: (ctx, statte) {
       context.go("/home");
     },
   ...

选项2

为您的 GoRouter 定义一个全局密钥,并使用它从您的 BLoC 进行导航。

/// Root navigator key.
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();

/// Navigation router.
final GoRouter kRouter = new GoRouter(
  navigatorKey: rootNavigatorKey,
  ...
 void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
    
    await _deleteDatabase();

    rootNavigatorKey.currentContext!.go("/home");
  }
© www.soinside.com 2019 - 2024. All rights reserved.