Flutter setState 在 provider 中被多次调用
Flutter setState is called multiple times in provider
首先,我的英语显然不完美:我会尽力而为!
我对 Flutter 很陌生。主要思想是让我的应用程序的用户根据他的角色进入良好的屏幕。所有用户都存储在 FireStore 数据库中。
我的问题是 setState 函数似乎被调用了多次。
如果用户不为空,我想读取数据库中用户的 "role" 字段,然后根据他的角色,我希望将他重定向到管理页面或客户端页面。
要恢复,我只想读一次角色然后重定向。但正如我之前所说,如果我在 setState 中放置打印,它会被调用多次......我该怎么做才能解决这个问题?
谢谢!
@override
Widget build(BuildContext context) {
User user= Provider.of<User>(context);
final AuthService _auth=AuthService();
if(user ==null){
return SignIn();
} else{
getRoleWrapper(user).then((s) {
setState(() {
user.setRole(s);
});
});
if(user.role=="administrateur"){
return PageTestAdmin();
}else{
return BasicClient();
}
}
}
}
Future<String> getRoleWrapper (User user) async{
final AuthService _auth=AuthService();
String role=await _auth.getRole(user);
return role;
}
您要做的是在 .then 代码中添加重定向,以便在 setRole 完成后立即 运行。你不需要里面的 setState 因为它没有用。 setState 多次 运行 的原因是因为每当调用 setState 时,Widget build(...) 函数再次 运行 因此您将进入无限循环。一旦角色确定,就取出 setState 并重定向。我认为这会解决你的问题。您需要的代码如下。如果这解决了您的问题,请投票并接受它作为答案(单击复选标记)。
再更正一点。您可能必须在构建函数之外初始化您的用户变量和 _auth 变量。在 Dart/Flutter 中,在 setState 之后,整个构建又是 运行,因此这些变量不能在构建函数之外使用。考虑在 @override initState(...) 函数中初始化这些变量。
User user;
AuthService _auth;
bool isLoaded = false;
@override
void initState() {
super.initState();
user = Provider.of<User>(context);
AuthService _auth = AuthService();
}
@override
Widget build(BuildContext context) {
if (!isLoaded) {
if(user == null){
return SignIn();
}
else {
getRoleWrapper(user, _auth).then((s) {
user.setRole(s);
setState(() {
isLoaded = true;
});
});
}
}
return isLoaded ?
user.role == "administrateur" ?
PageTestAdmin() : BasicClient()
:
Container();
}
Future<String> getRoleWrapper (User user, AuthService auth) async{
String role = await auth.getRole(user);
return role;
}
首先,我的英语显然不完美:我会尽力而为! 我对 Flutter 很陌生。主要思想是让我的应用程序的用户根据他的角色进入良好的屏幕。所有用户都存储在 FireStore 数据库中。 我的问题是 setState 函数似乎被调用了多次。 如果用户不为空,我想读取数据库中用户的 "role" 字段,然后根据他的角色,我希望将他重定向到管理页面或客户端页面。 要恢复,我只想读一次角色然后重定向。但正如我之前所说,如果我在 setState 中放置打印,它会被调用多次......我该怎么做才能解决这个问题?
谢谢!
@override
Widget build(BuildContext context) {
User user= Provider.of<User>(context);
final AuthService _auth=AuthService();
if(user ==null){
return SignIn();
} else{
getRoleWrapper(user).then((s) {
setState(() {
user.setRole(s);
});
});
if(user.role=="administrateur"){
return PageTestAdmin();
}else{
return BasicClient();
}
}
}
}
Future<String> getRoleWrapper (User user) async{
final AuthService _auth=AuthService();
String role=await _auth.getRole(user);
return role;
}
您要做的是在 .then 代码中添加重定向,以便在 setRole 完成后立即 运行。你不需要里面的 setState 因为它没有用。 setState 多次 运行 的原因是因为每当调用 setState 时,Widget build(...) 函数再次 运行 因此您将进入无限循环。一旦角色确定,就取出 setState 并重定向。我认为这会解决你的问题。您需要的代码如下。如果这解决了您的问题,请投票并接受它作为答案(单击复选标记)。
再更正一点。您可能必须在构建函数之外初始化您的用户变量和 _auth 变量。在 Dart/Flutter 中,在 setState 之后,整个构建又是 运行,因此这些变量不能在构建函数之外使用。考虑在 @override initState(...) 函数中初始化这些变量。
User user;
AuthService _auth;
bool isLoaded = false;
@override
void initState() {
super.initState();
user = Provider.of<User>(context);
AuthService _auth = AuthService();
}
@override
Widget build(BuildContext context) {
if (!isLoaded) {
if(user == null){
return SignIn();
}
else {
getRoleWrapper(user, _auth).then((s) {
user.setRole(s);
setState(() {
isLoaded = true;
});
});
}
}
return isLoaded ?
user.role == "administrateur" ?
PageTestAdmin() : BasicClient()
:
Container();
}
Future<String> getRoleWrapper (User user, AuthService auth) async{
String role = await auth.getRole(user);
return role;
}