Flutter Provider中请求API前如何校验本地存储数据是否存在
解决方案
1. 新增本地用户数据校验逻辑
在调用API拉取Profile前,先检查本地存储的用户认证数据是否存在,避免空指针崩溃,同时提供明确的错误反馈。修改后的ProfileProvider代码如下:
class ProfileProvider extends ChangeNotifier { User? _user = null; bool isLoading = false; final _service = ProfileService(); User? get profile => _user; Future<User> getProfile({required BuildContext context}) async { // 已有缓存直接返回 if (_user != null) { return _user!; } isLoading = true; notifyListeners(); final userData = context.read<AppService>().getUserAuthData(); // 校验本地用户数据 if (userData == null) { isLoading = false; notifyListeners(); throw Exception("本地无用户认证数据,请重新登录"); } try { final res = await _service.get(userData: userData); _user = res; return res; } catch (e) { throw Exception("获取用户Profile失败:${e.toString()}"); } finally { isLoading = false; notifyListeners(); } } void setProfile(User user) { _user = user; notifyListeners(); } void removeProfile() { _user = null; notifyListeners(); } }
2. 上层调用时处理异常
在Widget中调用getProfile时,通过try-catch捕获异常,根据错误类型执行对应操作(比如跳转登录页):
// 示例Widget调用代码 ElevatedButton( onPressed: () async { final profileProvider = Provider.of<ProfileProvider>(context, listen: false); try { await profileProvider.getProfile(context: context); // 获取成功,执行页面跳转或UI刷新 } catch (e) { // 异常处理:弹窗提示+跳转登录 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.toString())), ); Navigator.pushReplacementNamed(context, '/login'); } }, child: const Text("加载用户信息"), )
3. 可选优化建议
- 给
AppService新增hasUserAuthData()方法,提前判断本地数据状态,减少Provider对上下文的依赖 - 封装自定义异常类(如
AuthDataMissingException),让上层错误处理更精准
内容的提问来源于stack exchange,提问作者Huzefa zeenwala
相关产品推荐
相关产品推荐

