Riverpod 状态在屏幕之间不持续

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

目前我面临一个问题,我在登录页面使用 AsyncNotifier,并且在身份验证提供程序中保存令牌,在用户提供程序中保存用户信息,但是当我尝试在个人资料屏幕中检索用户数据时,它显示为 null,似乎状态不在屏幕之间坚持......我做错了什么?

我的用户提供商:

@Riverpod(keepAlive: true)
class User extends _$User {
  @override
  Future<UserModel?> build() async => null;

  Future<void> setUser(UserModel user) async {
    state = AsyncData(user);
  }

  void signOut() {
    state = const AsyncData(null);
  }
}

我的身份验证提供商:

@riverpod
class Auth extends _$Auth {
  @override
  Future<AuthModel?> build() async => null;
  
  Future<void> login(String username, String password) async {
    var dio = getDio();
    var response = await dio.post(
      '/login',
      data: {
        'username': username,
        'password': password,
      },
    );

    state = AsyncData(AuthModel.fromJson(response.data));

    ref
        .read(userProvider.notifier)
        .setUser(UserModel.fromJson(response.data['user']));
  }
 
}

用户个人资料屏幕:

class ProfileScreen extends ConsumerWidget {
  const ProfileScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    var user = ref.watch(userProvider);
 
    return Column(
        children: [
          Text("${user.value?.fullName}"), // null
          Text("${user.value?.login}") // null
        ]
);
}
}

登录页面:

class LoginScreen extends ConsumerStatefulWidget {
  const LoginScreen({super.key});

  @override
  ConsumerState<LoginScreen> createState() => _LoginScreenState();
}


class _LoginScreenState extends ConsumerState<LoginScreen> {
  final TextEditingController login = TextEditingController();
  final TextEditingController password = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          controller: login,
        ),
        TextField(
          controller: password,
        ),
        ElevatedButton(
            onPressed: () {
              final future = ref
                  .read(authProvider.notifier)
                  .login(
                    login.text,
                    password.text,
                  )
                  .then(
                    (_) => Navigator.pushNamed(context, "profile"),
                  );
            },
            child: Text("Login")),
      ],
    );
  }
}
flutter provider riverpod state-management
1个回答
0
投票

您只需在致电您未来的提供商之前添加添加

await
关键字即可。

await ref
                .read(authProvider.notifier)
                .login(
                  login.text,
                  password.text,
                )
                .then(
                    (_) => Navigator.pushNamed(context, "profile"));
© www.soinside.com 2019 - 2024. All rights reserved.