【发布时间】:2021-03-03 17:19:10
【问题描述】:
我的提供程序包有问题。
我希望能够清除提供者ChangeNotifier 类的属性(_user = null)(这是一个注销功能)。
问题是当我从一个使用来自此提供程序的信息的小部件中执行此操作时。
我的主要应用是这样的:
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => AuthProvider(),
builder: (context, _) => App(),
),
);
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<AuthProvider>(builder: (_, auth, __) {
Widget displayedWidget;
switch (auth.loginState) {
case ApplicationLoginState.initializing:
displayedWidget = LoadingAppScreen();
break;
case ApplicationLoginState.loggedIn:
displayedWidget = HomeScreen();
break;
case ApplicationLoginState.loggedOut:
default:
displayedWidget = AuthenticationScreen(
signInWithEmailAndPassword: auth.signInWithEmailAndPassword,
registerAccount: auth.registerAccount,
);
}
return MaterialApp(
title: 'My App',
home: displayedWidget,
routes: {
ProfileScreen.routeName: (_) => ProfileScreen(),
},
);
});
}
}
我的 Provider 类(简体):
class AuthProvider extends ChangeNotifier {
ApplicationLoginState _loginState;
ApplicationLoginState get loginState => _loginState;
bool get loggedIn => _loginState == ApplicationLoginState.loggedIn;
User _user;
User get user => _user;
void signOut() async {
// Cleaning the user which lead to the error later
_user = null;
_loginState = ApplicationLoginState.loggedOut;
notifyListeners();
}
}
可通过命名路线访问的“我的个人资料”屏幕
class ProfileScreen extends StatelessWidget {
static const routeName = '/profile';
@override
Widget build(BuildContext context) {
final User user = Provider.of<AuthProvider>(context).user;
return Scaffold(
// drawer: AppDrawer(),
appBar: AppBar(
title: Text('Profile'),
),
body: Column(
children: [
Text(user.displayName),
FlatButton(
child: Text('logout'),
onPressed: () {
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(builder: (BuildContext context) => App()),
// ModalRoute.withName('/'),
// );
Provider.of<AuthProvider>(context, listen: false).signOut();
},
)
],
),
);
}
}
当我从个人资料屏幕单击注销按钮时,我不明白为什么会出现错误:
由于我在我的应用程序的顶层使用Consumer<AuthProvider>(这包括我的路线(ProfileScreen),我认为它会重定向到AuthenticationScreen,因为displayedWidget 是从switch 计算出来的.
但似乎重建ProfileScreen首先导致错误。 displayedWidget 的更改似乎没有任何影响。
我对 Provider 还是很陌生。我不明白我在这里的提供者模式中缺少什么?我的App / Consumer 用错了吗?
我希望你能帮助我理解我在这里做错了什么!谢谢。
注意:注释的Navigator.pushAndRemoveUntil 正确重定向到登录屏幕,但我可以在几毫秒内看到错误屏幕。
【问题讨论】: