简体   繁体   English

Flutter 和 Riverpod 卡在加载中 state

[英]Flutter with Riverpod is stuck in loading state

I'm coding on Login page with Riverpod, everything go fine but when user is try to login, system is stuck on loading state and didn't send data to data state. I don't know why.我正在使用 Riverpod 在登录页面上编码,go 一切正常,但是当用户尝试登录时,系统卡在加载 state 并且没有将数据发送到数据 state。我不知道为什么。

my code is like this: login form -> login controller -> login repository, then send data back to login form and redirect to dashboard.我的代码是这样的:登录表单 -> 登录 controller -> 登录存储库,然后将数据发送回登录表单并重定向到仪表板。

this code in login page登录页面中的此代码

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)))
          ],
        ),
      ),
    );
  }
}

then, this is controller然后,这是 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"]);
});

then, this is repository然后,这是存储库

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();
});

can anyone tell me, what is wrong?谁能告诉我,怎么了?

thank you谢谢你

Looks overly complicated, I would simplify a lot.看起来过于复杂,我会简化很多。 Something like this:是这样的:

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