微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何访问riverpod中statenotifier中的值和函数

如何解决如何访问riverpod中statenotifier中的值和函数

我使用 Riverpod 中的 statenotifier 实现了用户身份验证,但我不知道它是如何以这种方式工作的。我必须创建两个提供程序,一个 StateNotifierProvider 用于读取值,一个 Provider 用于相同的 statenotifier 以访问 statenotifier 中的函数

final signInStateNotifierProvider =
    StateNotifierProvider((ref) => SignInStateNotifier(authentication));

final signInProvider =
    Provider((ref) => ref.watch(signInStateNotifierProvider));

这是我的 statenotifier 类

class SignInStateNotifier extends StateNotifier<AuthFormStates> {
  SignInStateNotifier(this._authFacade) : super(AuthFormStates.initial());

  final SignInAuthFacade _authFacade;

  Future mapEventToState(SignInFormEvents event) async {
    event.map(
      // email changed
      emailChanged: (event) {
        state = state.copyWith(
          emailAddress: EmailAddress(event.email),authFailureOrSuccess: none(),);
      },// password changed
      passwordChanged: (event) {
        state = state.copyWith(
          password: Password(event.password),signInWithEmailAndPasswordpressed: (event) async {
        await _performActionWithEmailAndPassword(
          _authFacade.signInWithEmailAndPassword,);
  }

  Future _performActionWithEmailAndPassword(
    Future<Either<AuthFailure,Unit>> Function({
      @required EmailAddress emailAddress,@required Password password,})
        action,) async {
    Either<AuthFailure,Unit> result;
    final isEmailValid = state.emailAddress.isValid();
    final isPasswordValid = state.password.isValid();

    if (isEmailValid && isPasswordValid) {
      state = state.copyWith(
        isSubmitting: true,);

      result = await action(
        emailAddress: state.emailAddress,password: state.password,);

      state = state.copyWith(
        authFailureOrSuccess: some(result),);
    }
    state = state.copyWith(
      isSubmitting: false,showErrorMessage: true,authFailureOrSuccess: optionOf(result),);
  }
}

这就是我访问 statenotifier 的方式

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: ProviderListener<AuthFormStates>(
          provider: signInStateNotifierProvider.state,onChange: (context,state) {
            state.authFailureOrSuccess.fold(
              () {},(either) => either.fold(
                (failure) {
                  return null;
                },(success) => null,),);
          },child: Consumer(
            builder: (context,watch,child) {
              final providerState = watch(signInProvider);
              final stateNotifierState =
                  watch(signInStateNotifierProvider.state);
              return Form(
                  autovalidateMode: AutovalidateMode.onUserInteraction,child: Column(
                    children: [
                      TextFormField(
                        onChanged: (value) => providerState.mapEventToState(
                            SignInFormEvents.emailChanged(value)),validator: (_) => stateNotifierState
                            .emailAddress.validatedobject
                            .fold(
                                (l) => l.maybeMap(
                                    orElse: () => null,invalidEmail: (_) => 'Invalid Email'),(_) => null),TextFormField(
                        onChanged: (value) => providerState.mapEventToState(
                            SignInFormEvents.passwordChanged(value)),validator: (_) =>
                            stateNotifierState.password.validatedobject.fold(
                                (l) => l.maybeMap(
                                    orElse: () => null,invalidPassword: (_) => 'Invalid Password'),TextButton(
                          onpressed: () {
                            providerState.mapEventToState(const SignInFormEvents
                                .signInWithEmailAndPasswordpressed());
                          },child: const Text('Hello World'))
                    ],));
            },);
  }
}

这很好用,但我需要知道这是正确的方法还是我错了。有没有其他方法可以实现我正在做的事情?请给出解决方案。

而且我所做的也是正确的,请告诉我它是如何以这种方式工作的。我需要清楚地了解它的工作原理。

提前致谢:)

解决方法

我认为 signInProvider 是多余的。它没有什么特别的,只是听signInStateNotifierProvider

在小部件 HomePage 中,您实际上可以使用 context.read(provider) 调用提供程序内部的函数而无需查看状态,因此您可以更改:

final providerState = watch(signInProvider);
providerState.mapEventToState(...)

final providerState = context.read(signInStateNotifierProvider);
providerState.mapEventToState(...)

context.read(signInStateNotifierProvider).mapEventToState(...)

另外,如果你追求最好的表现,你在验证价值时不需要听(看)signInStateNotifierProvider。 (因为你没有在widget树中重建任何东西,只是获取数据)

validator: (_) => context.read(signInStateNotifierProvider).emailAddress.validatedObject...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?