簡體   English   中英

如何使用 riverpod 2 初始化小部件的提供程序?

[英]How to initialize widget's provider with riverpod 2?

我的問題是關於 Riverpod 的。

我有一個帶有 2 個選項卡的小部件。 當我更改選項卡時,如果我選擇第一個選項卡,我想用“地址”值更新屬性(infoShare),如果我選擇第二個選項卡,我想用“publicKey”值更新屬性(infoShare)。

我用通知程序來做到這一點。 沒問題。 但是當我第一次實例化主要小部件時,我的提供者沒有初始化。 所以我需要修復它以創建一個特定的提供程序來初始化它並使用 ProviderScope。

這是初始化我的小部件的好方法嗎?

這是我的代碼。 它有效,但我不知道它是否是好的解決方案。 也許 Riverpod 的注釋會有所幫助

final _contactDetailInfoShareProviderArgs = Provider<Contact>(
  (ref) {
    throw UnimplementedError();
  },
);

final _contactDetailInfoShareProvider = NotifierProvider.autoDispose
    .family<ContactDetailInfoShareNotifier, String, Contact>(
  () {
    return ContactDetailInfoShareNotifier();
  },
);

class ContactDetailInfoShareNotifier
    extends AutoDisposeFamilyNotifier<String, Contact> {
  ContactDetailInfoShareNotifier();

  @override
  String build(Contact arg) {
    return arg.address.toUpperCase();
  }

  void setInfoShare(int tab, Contact contact) {
    if (tab == 1) {
      state = contact.publicKey.toUpperCase();
    } else {
      state = contact.address.toUpperCase();
    }
  }
}

abstract class ContactDetailProvider {
  static final contactDetailInfoShare = _contactDetailInfoShareProvider;
  static final contactDetailInfoShareProviderArgs =
      _contactDetailInfoShareProviderArgs;
}

class ContactDetail extends ConsumerWidget {
  const ContactDetail({
    required this.contact,
    super.key,
  });

  final Contact contact;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return ProviderScope(
      overrides: [
        ContactDetailProvider.contactDetailInfoShareProviderArgs
            .overrideWithValue(
          contact,
        ),
      ],
      child: ContactDetailBody(
        contact: contact,
      ),
    );
  }
}

class ContactDetailBody extends ConsumerWidget {
  const ContactDetailBody({
    required this.contact,
    super.key,
  });

  final Contact contact;
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Column(
      children: <Widget>[
        Expanded(
          child: Container(
            child: ContainedTabBarView(
              tabs: [
                Text('tab1'),
                Text('tab2'),
              ],
              views: [
                ContactDetailTab1(),
                ContactDetailTab2(),
              ],
              onChange: (p0) {
                ref
                    .watch(
                      ContactDetailProvider.contactDetailInfoShare(contact)
                          .notifier,
                    )
                    .setInfoShare(p0, contact);
              },
            ),
          ),
        ),
        AppButton(
          'Share',
          onPressed: () {
            print(
              ref.watch(
                ContactDetailProvider.contactDetailInfoShare(
                  ref.read(
                    ContactDetailProvider.contactDetailInfoShareProviderArgs,
                  ),
                ),
              ),
            );
          },
        )
      ],
    );
  }
}

ProviderScope不應用於您的應用程序的根以外,或僅用於測試。 它不是為在您的小部件中使用而設計的。 還有許多其他選項可以初始化您的提供者,考慮使用.family或使用一些具有三種狀態的StateNotifierProvider loadingerrorvalue ,您可以loading初始值,初始化后您可以獲得value state 。或者考慮使用新的Riverpod代碼生成有一些更復雜的邏輯來初始化你的提供者。

暫無
暫無

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

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