Flutter使用Fluro路由重载页面报GlobalKey重复使用错误如何解决
问题现象
项目接入Fluro实现路由导航时,页面重载触发以下报错:
Another exception was thrown: A GlobalKey was used multiple times inside one widget's child list.
对应MaterialApp实现代码片段如下:
class MyApp extends StatefulWidget { @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { _MyAppState() { final router = FluroRouter.appRouter; AppRouter.setupRouter(router); AppRouter.router = router; } @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider( create: (ctx) => Auth(), ), ListenableProxyProvider<Auth, Orders>( update: (_, authObj, prevOrders) => Orders(authObj.usrName, authObj.objId) ], child: MaterialApp( initialRoute: root, onGenerateRoute: AppRouter.router.generator, debugShowCheckedModeBanner: false, home: authData.isAuth ? TabsScreen() : FutureBuilder( initialData: authData.tryLogin(), future: authData.tryLogin(), builder: (_, snapshot) => snapshot.connectionState == ConnectionState.waiting ? SplashScreen() : AuthScreen()), );
故障原因
- 路由配置冲突:MaterialApp不允许同时配置
home属性和initialRoute+onGenerateRoute路由方案,二者同时存在时,Flutter初始化路由栈会重复挂载根节点,直接导致GlobalKey被重复引用。 - 路由初始化时机错误:Fluro路由初始化逻辑写在State构造函数中,热重载、State重建时构造函数会重复执行,导致路由表重复注册、路由实例重复生成,同一路由页的GlobalKey会被多次加入Widget树。
- 异步逻辑重复触发:FutureBuilder的
future和initialData直接在build方法中调用authData.tryLogin()赋值,每次页面重建都会重新执行登录校验、重复刷新页面组件,进一步放大GlobalKey重复挂载的问题。
解决步骤
- 移除路由配置冲突:删除MaterialApp的
home属性,将首页、登录页、启动页都注册到Fluro路由表中,统一由onGenerateRoute做路由分发,登录鉴权逻辑放到Fluro的路由守卫中判断跳转目标即可。 - 调整路由初始化位置:把Fluro路由初始化逻辑从State构造函数移到
main()函数的runApp之前执行,保证全局路由只初始化一次,不会随组件重建重复注册。
修正后的入口代码示例:void main() { // 全局路由仅初始化一次 final router = FluroRouter.appRouter; AppRouter.setupRouter(router); AppRouter.router = router; runApp(const MyApp()); } - 修复FutureBuilder重复执行问题:不要在build方法中直接给FutureBuilder传异步方法调用,提前在State的
initState生命周期中缓存异步实例,避免每次build都重新触发异步任务、重建组件。 - 全局排查GlobalKey使用:检查所有页面中定义的GlobalKey,确保没有在build方法中临时创建GlobalKey,每个GlobalKey仅绑定一个Widget实例,不存在全局重复引用的情况。
内容的提问来源于stack exchange,提问作者Behnam
相关产品推荐
相关产品推荐

