GoRouter问题:返回上一页面后URL查询参数未清除
GoRouter Web端返回页面后URL查询参数未清除问题

从页面返回上一页面时,URL中的查询参数并未被清除,Web端URL表现如下:
- 预期结果:浏览器地址栏显示
#/ - 实际结果:浏览器地址栏显示
#/?sort=asc
使用版本:go_route: ^6.0.0
复现代码
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:go_router/go_router.dart'; final Map<String, dynamic> _families = { "f1": { "name": "Doe", "people": { "p1": {"name": "Jane", "age": 23}, "p2": {"name": "John", "age": 6} } }, "f2": { "name": "Wong", "people": { "p1": {"name": "June", "age": 51}, "p2": {"name": "Xin", "age": 44} } } }; void main() => runApp(App()); /// The main app. class App extends StatelessWidget { /// Creates an [App]. App({Key? key}) : super(key: key); /// The title of the app. static const String title = 'GoRouter Example: Query Parameters'; // add the login info into the tree as app state that can change over time @override Widget build(BuildContext context) => MaterialApp.router( routerConfig: _router, title: title, debugShowCheckedModeBanner: false, ); late final GoRouter _router = GoRouter( initialLocation: '/', redirect: (context, state) { print('Subloc: ${state.subloc}'); }, debugLogDiagnostics: true, routerNeglect: true, routes: <GoRoute>[ GoRoute( path: '/', builder: (BuildContext context, GoRouterState state) { return const HomeScreen(); }, routes: <GoRoute>[ GoRoute( name: 'family', path: 'family/:fid', builder: (BuildContext context, GoRouterState state) { return FamilyScreen( fid: state.params['fid']!, asc: state.queryParams['sort'] == 'asc', ); }), ], ), ], ); } /// The home screen that shows a list of families. class HomeScreen extends StatelessWidget { /// Creates a [HomeScreen]. const HomeScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: const Text(App.title), ), body: ListView( children: <Widget>[ for (final String fid in _families.keys) ListTile( title: Text(_families[fid]['name']), onTap: () { context.goNamed( 'family', params: {'fid': fid}, queryParams: {'sort': 'asc'}, ); }, ) ], ), ); } } /// The screen that shows a list of persons in a family. class FamilyScreen extends StatelessWidget { /// Creates a [FamilyScreen]. const FamilyScreen({required this.fid, required this.asc, Key? key}) : super(key: key); /// The family to display. final String fid; /// Whether to sort the name in ascending order. final bool asc; @override Widget build(BuildContext context) { final Map<String, String> newQueries; final List<String> names = _families[fid]['people'] .values .map<String>((dynamic p) => p['name'] as String) .toList(); names.sort(); if (asc) { newQueries = const <String, String>{'sort': 'desc'}; } else { newQueries = const <String, String>{'sort': 'asc'}; } return Scaffold( appBar: AppBar( title: Text(_families[fid]['name']), leading: BackButton( onPressed: () { GoRouter.of(context).pop(); }, ), actions: <Widget>[ IconButton( onPressed: () { context.goNamed('family', params: <String, String>{'fid': fid}, queryParams: newQueries); }, tooltip: 'sort ascending or descending', icon: const Icon(Icons.sort), ) ], ), body: ListView( children: <Widget>[ for (final String name in asc ? names : names.reversed) ListTile( title: Text(name), ), ], ), ); } }
解决办法
方式一:修改返回按钮逻辑(推荐)
原代码用pop()返回时,会回到历史栈中的上一条记录,但Family页面内用goNamed替换了当前路由,导致返回时首页URL被带上参数。直接导航到首页路径,确保参数被清除:
leading: BackButton( onPressed: () { // 替换pop,直接跳转到首页 context.go('/'); }, ),
方式二:清理首页的查询参数
在HomeScreen的build方法中,检查当前路由是否带有多余参数,若有则自动清理:
@override Widget build(BuildContext context) { final state = GoRouterState.of(context); // 若存在查询参数,导航回纯净的首页路径 if (state.queryParams.isNotEmpty) { WidgetsBinding.instance.addPostFrameCallback((_) { context.go('/'); }); } return Scaffold( // 原有页面代码... ); }
方式三:调整路由配置
当前路由设置了routerNeglect: true,会忽略导航记录,可能导致历史栈异常。若不需要该特性,可将其改为false:
late final GoRouter _router = GoRouter( initialLocation: '/', redirect: (context, state) { print('Subloc: ${state.subloc}'); }, debugLogDiagnostics: true, routerNeglect: false, // 修改为false routes: <GoRoute>[ // 原有路由配置... ], );
内容的提问来源于stack exchange,提问作者Aadi
相关产品推荐
相关产品推荐

