错误:如果提供了routerConfig,就不能提供其他路由委托(GoRouting包)。

huangapple go评论72阅读模式
英文:

error: If the routerConfig is provided, all the other router delegates must not be provided (GoRouting Package)

问题

我想创建一个使用 GoRoute 和 Riverpod 的身份验证流程。

如下所示:

  1. 显示启动屏幕。
  2. 在显示启动屏幕时检查用户是否有令牌。
  3. 根据结果,将用户导航到登录屏幕或主屏幕。

尝试运行应用程序时出现此错误:

════════ Exception caught by widgets library ═══════════════════════════════════
发生以下断言,构建 MaterialApp(dirty, state: _MaterialAppState#8a7c5):
如果提供了routerConfig,则不能提供所有其他router委托
'package:flutter/src/widgets/app.dart':
app.dart:1
断言失败: 行 454 位置 14: '(routeInformationProvider ?? routeInformationParser ?? routerDelegate ?? backButtonDispatcher) == null'

AppRouting 类:

类 AppRouting {
  // final appService;
  final Ref ref;

  GoRouter 获取路由 => _routes;

  AppRouting({
    required this.ref,
  });

  稍后 final appService = ref.watch(appServiceProvider);
  稍后 final _routes = GoRouter(
    refreshListenable: appService,
    initialLocation: APP_PAGE.home.toPath,
    routes: [
      GoRoute(
        name: APP_PAGE.home.toName,
        path: APP_PAGE.home.toPath,
        // 构建: (context, state) => const HomeScreen(),
        构建: (context, state) => const LoginScreen(),
      ),
      GoRoute(
        name: APP_PAGE.login.toName,
        path: APP_PAGE.login.toPath,
        构建: (context, state) => const LoginScreen(),
      ),
      GoRoute(
        name: APP_PAGE.resetPassword.toName,
        path: APP_PAGE.resetPassword.toPath,
        构建: (context, state) => const ResetPasswordScreen(),
      ),
      GoRoute(
        name: APP_PAGE.listView.toName,
        path: APP_PAGE.listView.toPath,
        构建: (context, state) => ListViewScreen(),
      ),
      GoRoute(
        name: APP_PAGE.palettQrCode.toName,
        path: APP_PAGE.palettQrCode.toPath,
        构建: (context, state) => PalettQrCode(),
      ),
      GoRoute(
        name: APP_PAGE.settings.toName,
        path: APP_PAGE.settings.toPath,
        构建: (context, state) => SettingScreen(),
      ),
      // GoRoute(
      //   name: AppRoutingConstans.girdViewRouteName,
      //   path: GridViewScreen.screenPath,
      //   构建: (context, state) => GridViewScreen(),
      // ),
      GoRoute(
        name: APP_PAGE.productPicker.toName,
        path: APP_PAGE.productPicker.toPath,
        构建: (context, state) => ProductPickUpScreen(),
      ),
      GoRoute(
        name: APP_PAGE.error.toName,
        path: APP_PAGE.error.toPath,
        构建: (context, state) => ErrorScreen(
          error: state.extra.toString(),
        ),
      ),
      GoRoute(
        name: APP_PAGE.splash.toName,
        path: APP_PAGE.splash.toPath,
        构建: (context, state) => const SplashScreen(),
      ),
    ],
    errorBuilder: (context, state) => ErrorScreen(
      error: state.error.toString(),
    ),
    redirect: (context, state) {
      final splashLocation = state.namedLocation(APP_PAGE.splash.toPath);
      final homeLocation = state.namedLocation(APP_PAGE.home.toPath);
      final loginLocation = state.namedLocation(APP_PAGE.login.toPath);

      final isLogedIn = appService.loginState;
      final isInitialized = appService.initialized;

      final isGoingToLogin = state.path == loginLocation;
      final isGoingToInit = state.path == splashLocation;

      打印(state.path);

      // 如果未初始化且不前往初始化,则重定向到Splash
      如果 (!isInitialized && !isGoingToInit) {
        return splashLocation;
        // 如果未登录且不前往登录,则重定向到登录
      } else if (isInitialized && !isLogedIn && !isGoingToLogin) {
        return loginLocation;
        // 如果所有情景都清除了,但仍然前往屏幕之一,则重定向到主屏幕
      } else if ((isLogedIn && isGoingToLogin) ||
          (isInitialized && isGoingToInit)) {
        return homeLocation;
      } else {
        // 否则不要做任何事
        返回 null;
      }
    },
  );
}

// GoRouter 配置

final goRouterProvider = Provider<AppRouting>((ref) {
  返回 AppRouting(ref: ref);
});

在 main.dart 中:

类 MyApp 扩展 ConsumerStatefulWidget {
  const MyApp({super.key});

  @override
  ConsumerState<ConsumerStatefulWidget> createState() => _MyAppState();
}

类 _MyAppState 扩展 ConsumerState<MyApp> {
  @override
  Widget build(BuildContext context) {
    final goRouter = ref.read(goRouterProvider).router;

    返回 MaterialApp.router(
      ...
      routerConfig: goRouter,
      routeInformationProvider: goRouter.routeInformationProvider,
      routeInformationParser: goRouter.routeInformationParser,
      routerDelegate: goRouter.routerDelegate,
      ...
    );
  }
}
英文:

I want to create an authentication flow with GoRoute and Riverpod.

the as the following:

  1. display a splash screen.
  2. while the splash screen is displayed check if the user has a token or not.
  3. based on the result either navigate the user to the login screen or the home screen.

when trying to run the application this error occurred:

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building MaterialApp(dirty, state: _MaterialAppState#8a7c5):
If the routerConfig is provided, all the other router delegates must not be provided
&#39;package:flutter/src/widgets/app.dart&#39;:
app.dart:1
Failed assertion: line 454 pos 14: &#39;(routeInformationProvider ?? routeInformationParser ?? routerDelegate ?? backButtonDispatcher) == null&#39;

AppRouting class:

class AppRouting {
// final appService;
final Ref ref;
GoRouter get router =&gt; _routes;
AppRouting({
required this.ref,
});
late final appService = ref.watch(appServiceProvider);
late final _routes = GoRouter(
refreshListenable: appService,
initialLocation: APP_PAGE.home.toPath,
routes: [
GoRoute(
name: APP_PAGE.home.toName,
path: APP_PAGE.home.toPath,
// builder: (context, state) =&gt; const HomeScreen(),
builder: (context, state) =&gt; const LoginScreen(),
),
GoRoute(
name: APP_PAGE.login.toName,
path: APP_PAGE.login.toPath,
builder: (context, state) =&gt; const LoginScreen(),
),
GoRoute(
name: APP_PAGE.resetPassword.toName,
path: APP_PAGE.resetPassword.toPath,
builder: (context, state) =&gt; const ResetPasswordScreen(),
),
GoRoute(
name: APP_PAGE.listView.toName,
path: APP_PAGE.listView.toPath,
builder: (context, state) =&gt; ListViewScreen(),
),
GoRoute(
name: APP_PAGE.palettQrCode.toName,
path: APP_PAGE.palettQrCode.toPath,
builder: (context, state) =&gt; PalettQrCode(),
),
GoRoute(
name: APP_PAGE.settings.toName,
path: APP_PAGE.settings.toPath,
builder: (context, state) =&gt; SettingScreen(),
),
// GoRoute(
//   name: AppRoutingConstans.girdViewRouteName,
//   path: GridViewScreen.screenPath,
//   builder: (context, state) =&gt; GridViewScreen(),
// ),
GoRoute(
name: APP_PAGE.productPicker.toName,
path: APP_PAGE.productPicker.toPath,
builder: (context, state) =&gt; ProductPickUpScreen(),
),
GoRoute(
name: APP_PAGE.error.toName,
path: APP_PAGE.error.toPath,
builder: (context, state) =&gt; ErrorScreen(
error: state.extra.toString(),
),
),
GoRoute(
name: APP_PAGE.splash.toName,
path: APP_PAGE.splash.toPath,
builder: (context, state) =&gt; const SplashScreen(),
),
],
errorBuilder: (context, state) =&gt; ErrorScreen(
error: state.error.toString(),
),
redirect: (context, state) {
final splashLocation = state.namedLocation(APP_PAGE.splash.toPath);
final homeLocation = state.namedLocation(APP_PAGE.home.toPath);
final loginLocation = state.namedLocation(APP_PAGE.login.toPath);
final isLogedIn = appService.loginState;
final isInitialized = appService.initialized;
final isGoingToLogin = state.path == loginLocation;
final isGoingToInit = state.path == splashLocation;
print(state.path);
// If not Initialized and not going to Initialized redirect to Splash
if (!isInitialized &amp;&amp; !isGoingToInit) {
return splashLocation;
// If not logedin and not going to login redirect to Login
} else if (isInitialized &amp;&amp; !isLogedIn &amp;&amp; !isGoingToLogin) {
return loginLocation;
// If all the scenarios are cleared but still going to any of that screen redirect to Home
} else if ((isLogedIn &amp;&amp; isGoingToLogin) ||
(isInitialized &amp;&amp; isGoingToInit)) {
return homeLocation;
} else {
// Else Don&#39;t do anything
return null;
}
},
);
}
// GoRouter configuration
final goRouterProvider = Provider&lt;AppRouting&gt;((ref) {
return AppRouting(ref: ref);
});

in main.dart

class MyApp extends ConsumerStatefulWidget {
const MyApp({super.key});
@override
ConsumerState&lt;ConsumerStatefulWidget&gt; createState() =&gt; _MyAppState();
}
class _MyAppState extends ConsumerState&lt;MyApp&gt; {
@override
Widget build(BuildContext context) {
final goRouter = ref.read(goRouterProvider).router;
return MaterialApp.router(
...
routerConfig: goRouter,
routeInformationProvider: goRouter.routeInformationProvider,
routeInformationParser: goRouter.routeInformationParser,
routerDelegate: goRouter.routerDelegate,
...
);
}
}

答案1

得分: 2

从错误消息中:

如果提供了 routerConfig,则不能提供其他路由代理。

将此更改为:

return MaterialApp.router(
  ...
  routerConfig: goRouter,
  ...
);
英文:

From the error message:

If the routerConfig is provided, all the other router delegates must not be provided.

Change this:

return MaterialApp.router(
...
routerConfig: goRouter, // &lt;== provided
routeInformationProvider: goRouter.routeInformationProvider, // &lt;== not needed
routeInformationParser: goRouter.routeInformationParser, // &lt;== not needed
routerDelegate: goRouter.routerDelegate, // &lt;== not needed
...
);

To this:

return MaterialApp.router(
...
routerConfig: goRouter,
...
);

huangapple
  • 本文由 发表于 2023年5月22日 22:29:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76307222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定