簡體   English   中英

Flutter 和 Riverpod 卡在加載中 state

[英]Flutter with Riverpod is stuck in loading state

我正在使用 Riverpod 在登錄頁面上編碼,go 一切正常,但是當用戶嘗試登錄時,系統卡在加載 state 並且沒有將數據發送到數據 state。我不知道為什么。

我的代碼是這樣的:登錄表單 -> 登錄 controller -> 登錄存儲庫,然后將數據發送回登錄表單並重定向到儀表板。

登錄頁面中的此代碼

class LoginPage extends ConsumerWidget {
  LoginPage({Key? key}) : super(key: key);

  final TextEditingController usernameController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Padding(
      padding: const EdgeInsets.all(20),
      child: Container(
        decoration: BoxDecoration(borderRadius: BorderRadius.circular(20)),
        padding: const EdgeInsets.all(20),
        child: Column(
          children: [
            Image.asset(
              "assets/images/logo.png",
              width: 80,
            ),
            const SizedBox(
              height: 20,
            ),
            TextField(
              controller: usernameController,
              decoration: const InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Email / Username',
              ),
            ),
            const SizedBox(
              height: 20,
            ),
            TextField(
              controller: passwordController,
              obscureText: true,
              decoration: const InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Password',
              ),
            ),
            const SizedBox(
              height: 20,
            ),
            TextButton(
                onPressed: () {
                  final loginDataValue = ref.watch(loginControllerProvider({
                    "username": usernameController.text,
                    "password": passwordController.text
                  }));

                  loginDataValue.when(
                      data: (userData) {
                        if (userData["isLoggedIn"]) {
                          GoRouter.of(context).goNamed("home");
                        }
                      },
                      error: (e, __) => debugPrint(e.toString()),
                      loading: () => debugPrint("loading"));
                },
                child: const Text("Sign in"),
                style: TextButton.styleFrom(
                    backgroundColor: const Color.fromARGB(255, 105, 240, 233),
                    primary: Colors.black87,
                    minimumSize: const Size(88, 36),
                    padding: const EdgeInsets.symmetric(horizontal: 16.0)))
          ],
        ),
      ),
    );
  }
}

然后,這是 controller

import 'package:calendar/repositories/login_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class LoginController extends StateNotifier<AsyncValue<Map>> {
  LoginController(this._loginRepository,
      {required this.username, required this.password})
      : super(const AsyncValue.loading()) {
    login(username: username, password: password);
  }
  final LoginRepository _loginRepository;
  final String username;
  final String password;

  Future<void> login(
      {required String username, required String password}) async {
    try {
      state = const AsyncValue.loading();
      final suggestions = await _loginRepository.loginUser(
          username: username, password: password);
      state = AsyncValue.data(suggestions);
    } catch (err) {
      state = AsyncValue.error(err);
    }
  }
}

final loginControllerProvider = StateNotifierProvider.autoDispose
    .family<LoginController, AsyncValue<Map>, Map>((ref, data) {
  final loginRepository = ref.watch(loginRepositoryProvider);
  return LoginController(loginRepository,
      username: data["username"], password: data["password"]);
});

然后,這是存儲庫

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class LoginRepository {
  Future<Map> loginUser(
      {required String username, required String password}) async {
    try {
      return {
        "username": username,
        "token": "tokenfromapi",
        "isLoggedIn": true
      };
    } catch (err) {
      throw AsyncValue.error(err);
    }
  }
}

final loginRepositoryProvider = Provider<LoginRepository>((ref) {
  return LoginRepository();
});

誰能告訴我,怎么了?

謝謝你

看起來過於復雜,我會簡化很多。 是這樣的:

final loginControllerProvider = FutureProvider.family<Map, Map>((ref, data) async {
  //TODO call login API
  return {
    "username": data["username"],
    "token": "tokenfromapi",
    "isLoggedIn": true
  };
});

暫無
暫無

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

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