【问题标题】:Riverpod not reloading consumer widget until hot reloadRiverpod 在热重新加载之前不会重新加载消费者小部件
【发布时间】:2021-09-18 08:36:19
【问题描述】:

我无法让 Riverpod 通知状态变化。我是 Riverpod 的新手,所以我可能误解了它的工作原理。

我想使用 Riverpod 提供一个对象变量,我在另一个小部件树上设置信息,然后将该类中的信息提供给单独的小部件树中的消费者。这个消费者在功能上充当一种窗口片段,我想在屏幕的这一部分中放置一个特定的小部件,由提供的对象中的信息确定。

这是我为对象设置的 Provider。

final userPageContext = StateProvider<UserPageContext>((ref) {
  return UserPageContext(ptContext: PageTypes.WELCOME);
});

这是我在显示特定小部件之前观察状态变化的消费者。

Consumer(
                builder: (context, ScopedReader watch, __) {
                  final pageContext = watch(userPageContext).state;
                  return getPageToDisplay(pageContext);
                },
              ),

此函数提供要显示的小部件。

  Widget getPageToDisplay(UserPageContext pageContext) {
    if (pageContext.entryReady) {
      return EntryScreen(entry: pageContext.getNewEntry());
    } else {
      return Container();
    }
  }

这是我更改所提供对象的状态的构建方法。

@override
  Widget build(BuildContext context) {
    return Consumer(builder: (_, ScopedReader watch, __) {

      final pageContext = watch(userPageContext).state;

      return Dialog(
        ... widgets ...
                Row(
                  ... widgets ...
                        // A button press confirms the users choice and then submits it to the provider
                        onPressed: () {
                          Entry entry = Entry(
                              entryType: entryType,
                              id: id,
                              name: name);

                          pageContext.ptContext = PageTypes.ENTRY;
                          pageContext.setNewEntry(entry);
                          pageContext.entryReady = true;

                          // These pops remove dialog menus that were in the current widget branch
                          Navigator.of(context).pop();
                          Navigator.of(context).pop();
                        },
                        ... widgets ...
                        ),
                      ),
                    )
                  ],
                )
              ],
            ),
          ),
        ),
      );
    });
  }

这是用于存储状态信息的类。

class UserPageContext {
  UserPageContext({required this.ptContext});

  late Entry _newEntry;
  bool entryReady = false;

  /// sets new entry and flags the class state to ready for listeners
  void setNewEntry(Entry entry) {
    _newEntry = entry;
    entryReady = true;
  }

  Entry getNewEntry() {
    entryReady = false;
    return _newEntry;
  }

  PageTypes ptContext;
}

我尝试了多种不同的方式来调用提供程序,从 context.read 和 watch 到 watch(object.notifier) 和 watch(object.notifier).state。我想我已经尝试了大多数可能性,所以我不确定这是否是我的问题的原因。

-- 小编辑-- 我忘了补充说,通过逻辑进行似乎工作正常,但在我执行热重载之前状态不会更新。然后出现预期的页面。然而,奇怪的是,页面在另一次热重新加载后立即消失。这似乎表明我提供给提供者的信息在使用后立即被重写,或者我以某种方式没有更改提供者?老实说,我不确定。

提前感谢您,希望您有美好的一天!

【问题讨论】:

  • 您好,欢迎来到 StackOverflow。您能否为您的提供者添加代码(userPageContext)?
  • 抱歉,添加了。此外,我最初使用 ChangeNotifier 扩展了对象类,但最终将其删除。当它使用 ChangeNotifier 进行扩展时,我尝试了 ChangeNotifierProvider,但我需要能够修改对象,而且似乎我不能或不理解语法。

标签: flutter riverpod


【解决方案1】:

我似乎已经解决了这个问题。我再次尝试使用 ChangeNotifierProvider。将它与扩展的 ChangeNotifier 结合使用,并确保在适当的时间使用 NotifyListeners,似乎可以解决问题。

这是我最终使用的 Provider。

final userPageContext = ChangeNotifierProvider((ref) {
  return UserPageContext(ptContext: PageTypes.WELCOME);
});

这些是我对班级所做的更改。

class UserPageContext extends ChangeNotifier {

  /// sets new entry and flags the class state to ready for listeners
  void setNewEntry(Entry entry) {
    ... code ...
    notifyListeners();
  }
 ...

最后,我在第一次尝试 ChangeNotifier 时遇到的一个问题是它似乎没有状态访问权限,类似于许多其他用于 Riverpod 的提供程序的语法。事实证明,您不需要它,因为它只是在您观看时返回您正在寻找的对象。以下是我调用提供者的方式。

final pageContext = watch(userPageContext);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-03
    • 2012-02-12
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    相关资源
    最近更新 更多