不要跨异步间隙使用“BuildContext”

问题描述 投票:0回答:1

`不要跨异步间隙使用“BuildContext”。尝试重写代码以不引用“BuildContext”

所提供代码中的问题涉及处理异步操作以及在 Flutter 应用程序中跨异步间隙使用 BuildContext。

异步差距:代码包含异步操作,例如使用 http 包发出 HTTP 请求。但是,在某些情况下,代码会尝试访问异步函数中的 BuildContext,但通常不鼓励这样做,因为它可能会导致潜在问题,并且被认为是不好的做法。

传递上下文:BuildContext通常用于访问Flutter框架内的各种资源和小部件。但是,跨异步间隙传递 BuildContext 可能会导致问题,因为异步操作完成时上下文可能会变得无效或不可用。

错误处理:代码包括使用 try-catch 块进行错误处理,以处理异步操作期间可能发生的异常。但是,应审查错误处理机制,以确保正确处理并向用户报告错误。

Provider用法:代码利用Provider包来访问UserProvider并更新用户相关数据。但是,考虑到最佳实践和效率,可能有机会优化提供程序的使用方式。

HTTP 请求:代码向服务器 API 发出 HTTP 请求,包括注册和登录用户以及检索用户数据。应审查这些请求及其相关端点的实现,以确保正确性并遵守 API 规范。

SharedPreferences:代码使用 SharedPreferences 来存储和检索用户的身份验证令牌。应验证 SharedPreferences 的使用,以确保它正确处理令牌存储和检索。

总体而言,问题涉及重新编写代码以避免跨异步间隙传递 BuildContext、重新访问错误处理机制、优化提供程序的使用以及验证 HTTP 请求的实现和 SharedPreferences 的使用。 `

class AuthService {
  // sign up user
  void signUpUser({
    required BuildContext context,
    required String email,
    required String password,
    required String name,
  }) async {
    try {
      User user = User(
        id: '',
        name: name,
        password: password,
        email: email,
        address: '',
        type: '',
        token: '',
        cart: [],
      );

      http.Response res = await http.post(
        Uri.parse('$uri/api/signup'),
        body: user.toJson(),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
      );

      httpErrorHandle(
        response: res,
        context: context,
        onSuccess: () {
          showSnackBar(
            context,
            'Account created! Login with the same credentials!',
          );
        },
      );
    } catch (e) {
      showSnackBar(context, e.toString());
    }
  }

  // sign in user
  void signInUser({
    required BuildContext context,
    required String email,
    required String password,
  }) async {
    try {
      http.Response res = await http.post(
        Uri.parse('$uri/api/signin'),
        body: jsonEncode({
          'email': email,
          'password': password,
        }),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
      );
      httpErrorHandle(
        response: res,
        context: context,
        onSuccess: () async {
          SharedPreferences prefs = await SharedPreferences.getInstance();
          Provider.of<UserProvider>(context, listen: false).setUser(res.body);
          await prefs.setString('x-auth-token', jsonDecode(res.body)['token']);

          Navigator.pushNamedAndRemoveUntil(
            context,
            BottomBar.routeName,
            (route) => false,
          );
        },
      );
    } catch (e) {
      showSnackBar(context, e.toString());
    }
  }

  // get user data
  void getUserData(
    BuildContext context,
  ) async {
    try {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      String? token = prefs.getString('x-auth-token');

      if (token == null) {
        prefs.setString('x-auth-token', '');
      }

      var tokenRes = await http.post(
        Uri.parse('$uri/tokenIsValid'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
          'x-auth-token': token!
        },
      );

      var response = jsonDecode(tokenRes.body);

      if (response == true) {
        http.Response userRes = await http.get(
          Uri.parse('$uri/'),
          headers: <String, String>{
            'Content-Type': 'application/json; charset=UTF-8',
            'x-auth-token': token
          },
        );

        var userProvider = Provider.of<UserProvider>(context, listen: false);
        userProvider.setUser(userRes.body);
      }
    } catch (e) {
      showSnackBar(context, e.toString());
    }
  }
}

In this updated code, I added a reference to navigatorKey.currentContext to obtain the current Build Context within the methods. navigator Key is assumed to be a global key associated with a Navigator widget. 

http asynchronous error-handling sharedpreferences provider
1个回答
0
投票

好吧,我没有读你的问题,但希望这会有所帮助:

尝试在使用之前添加此内容

context
:

if (!context.mounted) return;.

或:

if (!mounted) return;
© www.soinside.com 2019 - 2024. All rights reserved.