我希望我的应用程序上的用户能够深入链接到配置文件页面,例如,用户可以转到“www.myapp.com/#/ user / {userId}”,我希望我的gorouter能够从uri中检测到{userId}变量,然后将数据输入状态通知器,状态通知器将为该用户获取应用程序中的详细信息。
我的代码看起来是这样的:
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routeInformationProvider: _router.routeInformationProvider,
routeInformationParser: _router.routeInformationParser,
routerDelegate: _router.routerDelegate,
);
}
final GoRouter _router = GoRouter(
initialLocation: '/login',
routes: <GoRoute>[
GoRoute(path: '/', builder: (context, state) => LoginSignupPage()),
GoRoute(path: '/login', builder: (context, state) => LoginSignupPage()),
GoRoute(
path: '/projects/:projectShortId',
builder: (context, state) {
var projectShortId = state.params['projectShortId']!;
return Consumer(
builder: (context, ref, child) {
ref
.read(projectStateNotifierProvider.notifier)
.setProjectFromCustomURI(projectShortId);
return ViewProjectPage();
},
);
},
)
],
);
}但是,当我运行它时,最初输入url "/projects/{userId1}“会很好,但是如果我键入一个不同的url "/projects/{userId2}",则会得到如下所示的重新构建错误(它们非常长,但后面有一系列update+rebuild框架错误):
Error: setState() or markNeedsBuild() called during build.
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw_
packages/flutter/src/widgets/framework.dart 4549:11 <fn>
packages/flutter/src/widgets/framework.dart 4563:14
markNeedsBuild
packages/flutter_riverpod/src/framework.dart 287:5
[_debugCanModifyProviders]
packages/riverpod/src/framework/provider_base.dart 513:42 <fn>
packages/riverpod/src/framework/provider_base.dart 337:7 setState
packages/riverpod/src/state_notifier_provider/auto_dispose.dart 118:10 listener
packages/state_notifier/state_notifier.dart 225:23 set state
packages/myapp_mvp/state/providers/project_state_provider/project_state_provider.dart 33:5
setProjectFromCustomURI发布于 2022-09-04 15:52:34
这个错误是在您试图构建一个Widget时引起的,而另一个则可能是因为您在一个构建器中调用了ref.notifier.read,这是一个非常糟糕的实践,如果您在内部设置状态,则会减慢您的应用程序的速度。我建议使用Go路由库中的navigatorBuilder为每个子Widget创建一个消费者包装器,并创建一个自定义通知器和状态来存储路由参数,然后从任何像您的ViewProjectPage一样的消费Widget中轻松地访问它们。
navigatorBuilder: (context, state, child) {
return Consumer(
builder: (_, ref, __) {
ref.watch(authControllerProvider).params = state.params;
return child;},
);
},来自线程的答案:How to define a GoRouter that depends on a Provider?
https://stackoverflow.com/questions/73600568
复制相似问题