flutter - 提供者登录注销颤动
问题描述
我正在尝试使用 Provider 创建一个简单的身份验证流程。我有三页:
- 登录页面
- 入职页面
- 主页
这个应用程序的流程是:
- 如果用户第一次打开应用程序,他/她将被重定向到入职页面,然后登录到主页。
- 对于第二次使用的用户,应用程序首先检查登录状态并重定向到登录 -> 主页或直接到主页。
这是我在代码中的设置:
主要.dart
void main() {
runApp(MultiProvider(providers: [
ChangeNotifierProvider<StorageHelper>(create: (_) => StorageHelper()),
ChangeNotifierProvider<AuthProvider>(create: (_) => AuthProvider()),
], child: MyApp()));
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return Consumer<AuthProvider>(builder: (final BuildContext context,
final AuthProvider authProvider, final Widget child) {
print(authProvider.isAuthenticated); // this is false whenever I //click the logout from category(or other pushed pages) but the below ternary //operation is not executing
return MaterialApp(
title: 'My Poor App',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(0xff29c17e),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: authProvider.isAuthenticated ? HomeScreen() : LoginScreen(),
onGenerateRoute: Router.onGenerateRoute,
);
});
}
}
登录界面.dart
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final authProvider = Provider.of<AuthProvider>(context, listen: false);
return Scaffold(
body: Center(
child: MaterialButton(
onPressed: () async {
await authProvider.emailLogin('user@email.com', 'pass');
},
child: Text('Login'))),
);
}
}
HomeScreen.dart
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthProvider>(context, listen: false);
return Scaffold(
body: Center(
child: MaterialButton(
elevation: 2,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CategoryScreen()));
},
child: Text('Reset')),
),
);
}
}
AuthProvider.dart
class AuthProvider extends ChangeNotifier {
bool _isAuthenticated = false;
bool get isAuthenticated => _isAuthenticated;
set isAuthenticated(bool isAuth) {
_isAuthenticated = isAuth;
notifyListeners();
}
Future emailLogin(String email, String password) async {
isAuthenticated = true;
}
Future logout() async {
isAuthenticated = false;
}
}
如果我从主页注销使用Provider.of<AuthProvider>(context).logout()
它工作正常。但是,如果我push
或pushReplacement
新路由并尝试从新路由注销(只是说我从主页导航到类别页面并尝试从那里注销),我不会被重定向到 LoginPage。如果我打印它的值,isAuthenticated
它会打印 false 但消费者没有听或至少没有对变量更改做出反应。
请不要将此问题标记为重复,我已经搜索了许多其他类似的问题,但没有一个适合我的案例。
编辑: CategoryScreen.dart
class CategoryScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
final auth = Provider.of<AuthProvider>(context, listen: false);
auth.logout();
// print(auth.isAuthenticated);
},
child: Text('Category Logout'),
),
),
);
}
}
解决方案
我猜你的问题是你没有使用Consumer
for logout
, in your home
in MaterialApp
。看看,如果它适合你
主要.dart
// needs to listen to the changes, to make changes
home: Consumer<AuthProvider>(
builder: (context, authProvider, child){
return authProvider.isAuthenticated ? HomeScreen() : LoginScreen();
}
)
由于,Consumer
不存在于您的home
, 即使值被更改, 它也无法根据提供者为您更新视图。
推荐阅读
- php - 用户登录后如何防止浏览器返回登录表单页面......?
- python - 如何使用 python 的 insert into 命令将数据从一个 SQL 服务器传输到另一个?
- android - 如何在开始时在android TextView中写入`@`符号
- c++ - loadGraph(): ERRORNot found: 未能加载计算图
- c++ - 我如何更改 std::cout
- python - 传递一个 tf.data.Dataset 将字典返回给 Keras
- php - 带有 ajax 函数调用的自动完成列表在 jquery.min.js 错误“s.send(t.hasContent && t.data || null)”中显示一个错误
- batch-file - 检查字符串是否以分号结尾
- python - 使用每日数据集绘制以月份为 x 轴的 seaborn 箱线图
- javascript - 无法在 Ext.draw.Container 构造函数中添加精灵