簡體   English   中英

Flutter api 使用riverpod登錄

[英]Flutter api login using riverpod

我正在嘗試使用 Riverpod 通過 laravel 后端登錄。 現在我只是從存儲庫中返回 true 或 false。 我設置了一個接受 email 和密碼的表單。 isLoading變量只是為了顯示一個圓形指示器。 我已經運行了代碼並且它可以工作,但不確定我是否正確使用了riverpod。 有更好的方法嗎?

auth_provider.dart

class Auth{
  final bool isLogin;
  Auth(this.isLogin);
}
class AuthNotifier extends StateNotifier<Auth>{
  AuthNotifier() : super(Auth(false));
  void isLogin(bool data){
    state = new Auth(data);
  }
}
final authProvider = StateNotifierProvider((ref) => new AuthNotifier());

auth_repository.dart

class AuthRepository{
  static String url = "http://10.0.2.2:8000/api/";
  final Dio _dio = Dio();
  Future<bool> login(data) async {
    try {
        Response response = await _dio.post(url+'sanctum/token',data:json.encode(data));
        return true;
    } catch (error) {
        return false;
    }
  }
}

login_screen.dart

void login() async{
  if(formKey.currentState.validate()){
    setState((){this.isLoading = true;});
    var data = {
      'email':this.email,
      'password':this.password,
      'device_name':'mobile_phone'
    };
    var result = await AuthRepository().login(data);
    if(result){
        context.read(authProvider).isLogin(true);
        setState((){this.isLoading = false;});
    }else
      setState((){this.isLoading = false;});
  }
}

由於我不是來自移動背景並且最近在我最近的項目中使用了flutter+riverpod,我不能說這是最佳實踐。 但有幾點我想說明:

  • 使用接口如IAuthRepository作為存儲庫。 Riverpod 可以充當依賴注入。
final authRepository = Provider<IAuthRepository>((ref) => AuthRepository());
  • 構建數據以發送到存儲庫。 如果可能,您應該將外部資源的表示、業務邏輯和顯式實現分開。
  Future<bool> login(String email, String password) async {
    try {
        var data = {
          'email': email,
          'password': password,
          'device_name':'mobile_phone'
        };
        Response response = await _dio.post(url+'sanctum/token',data:json.encode(data));
        return true;
    } catch (error) {
        return false;
    }
  }
  • 不要直接從演示/屏幕調用存儲庫。 您可以將提供程序用於您的邏輯,它調用存儲庫
class AuthNotifier extends StateNotifier<Auth>{
  final ProviderReference ref;
  IAuthRepository _authRepository;

  AuthNotifier(this.ref) : super(Auth(false)) {
    _authRepository = ref.watch(authRepository);
  }

  Future<void> login(String email, String password) async {
    final loginResult = await_authRepository.login(email, password);
    state = Auth(loginResult);
  }
}

final authProvider = StateNotifierProvider((ref) => new AuthNotifier(ref));

  • 在屏幕上,您可以調用提供商的login方法
login() {
  context.read(authProvider).login(this.email, this.password);
}
  • 使用 Consumer 或 ConsumerWidget 觀察 state 並決定構建什么。 它還有助於您可以創建其他一些 state,而不是使用 isLogin 進行 state 的Auth 至少,我通常會創建一個抽象的BaseAuthState ,它派生為AuthInitialStateAuthLoadingStateAuthLoginStateAuthErrorState等。
class AuthNotifier extends StateNotifier<BaseAuthState>{
  ...
  AuthNotifier(this.ref) : super(AuthInitialState()) { ... }
  ...
}
Consumer(builder: (context, watch, child) {
  final state = watch(authProvider.state);
  if (state is AuthLoginState) ...
  else if (state is AuthLoadingState) ...
  ...
})

我喜歡使用枚舉或 class 來驗證 state 而不是使用布爾值

enum AuthState { initialize, authenticated, unauthenticated }

並用於登錄 state

enum LoginStatus { initialize, loading, success, failed }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM