【问题标题】:Flutter Provider with listen false, but still get error "setState() or markNeedsBuild() called during build."侦听错误的 Flutter Provider,但仍然收到错误“setState() 或 markNeedsBuild() 在构建期间调用。”
【发布时间】:2021-12-05 20:43:26
【问题描述】:

我想在 networkProvider 更改时重置 userProvider。 在userProvider.reset(),我有notifyListeners

void didChangeDependencies() async {
  super.didChangeDependencies();
  final NetworkProvider networkProvider = Provider.of<NetworkProvider>(context);
  UserProvider userProvider = Provider.of<UserProvider>(context, listen: false);
  userProvider.reset(); }

当它运行时,它给出错误“setState() or markNeedsBuild() called during build.” 我的问题是,我已将监听设置为 false,为什么它仍然重建这个小部件?

只有一个UserProvider时,报同样的错误:

void didChangeDependencies() async {
  super.didChangeDependencies();
  UserProvider userProvider = Provider.of<UserProvider>(context, listen: false);
  userProvider.reset(); }

如果我的使用想法完全错误,有什么建议可以达到同样的效果吗?

【问题讨论】:

  • 你的构建方法是什么样的?如果您只是在阅读 UserProvider(使用 listen: false),那么这段代码不是问题。
  • 返回 MaterialApp(...)。是这个问题吗?

标签: flutter flutter-provider


【解决方案1】:

好吧,我找到了答案。它写在他们主页的后面。 我在我的问题中尝试的内容是不允许的,因为状态更新是同步的。

这意味着某些小部件可能会在突变发生之前构建(获取旧值),而其他小部件将在突变完成后构建(获取新值)。这可能会导致您的 UI 不一致,因此是不允许的。

相反,您应该在一个对整个树产生同样影响的地方执行该突变:

class MyNotifier with ChangeNotifier {
  MyNotifier() {
  _fetchSomething();
}

Future<void> _fetchSomething() async {
}

在构建中使用它:

Future.microtask(() =>
    context.read<MyNotifier>().fetchSomething(someValue);
);

【讨论】:

    【解决方案2】:

    因为您提到 NetworkProvider 发生了变化,我猜它也在发布通知,在这种情况下,您还希望这不会使用 listen: false 参数触发重建。不过,您似乎确实想要这些通知,以便您可以重置您的UserProvider。我建议您不要尝试在 Widget 的生命周期中执行此操作,而是使用 ProxyProvider 创建和更新您的 UserProvider,它依赖于 NetworkProvider

    【讨论】:

    • 我试图删除 NetworkProvider,所以只有一个 UserProvider。问题是一样的。
    猜你喜欢
    • 2021-04-12
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 2020-03-26
    • 2020-06-29
    相关资源
    最近更新 更多