【问题标题】:Provider plus FutureBuilder in Stateless Widget ConfusionStateless Widget 混淆中的 Provider 加 FutureBuilder
【发布时间】:2021-09-01 17:13:12
【问题描述】:

所以,我已经看到了使用 initState 函数将数据 (http) 加载到有状态小部件提供程序的示例。但是如果小部件是无状态的,我不确定最好的方法是什么。我所做的如下:

class GamesGrid extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final gamesData = Provider.of<GamesProvider>(context);
    return FutureBuilder<void>(
      future: gamesData.fetchGamesFromBgg(),
      builder: (ctx, AsyncSnapshot<void> snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          final games = gamesData.items;
          return GridView.builder(
              padding: const EdgeInsets.all(10.0),
              itemCount: games.length,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  childAspectRatio: 3 / 2,
                  crossAxisSpacing: 10,
                  mainAxisSpacing: 10),
              itemBuilder: (context, idx) => ChangeNotifierProvider.value(
                  value: games[idx],
                  child: GameItem()
              )
          );
        } else {
          return CircularProgressIndicator();
        }
      }
    );
  }
}

我只是不确定这是否是正确的方法。

【问题讨论】:

    标签: flutter dart flutter-provider flutter-futurebuilder


    【解决方案1】:

    如果您正在调用需要显示的未来,您应该使用有状态小部件并在 initState 或类似中获取未来。 documentation 不鼓励在 build 期间这样做,这是有充分理由的。

    未来一定是更早获得的,例如期间 State.initState、State.didUpdateWidget 或 State.didChangeDependencies。 不得在创建期间创建 构造时调用 State.build 或 StatelessWidget.build 方法 未来建造者。如果未来与 FutureBuilder,那么每次重建 FutureBuilder 的父级时, 异步任务将重新启动。

    如文档所述,如果GamesGridbuild 中获取future 时重新构建,则您的future 方法将被再次调用,这应该是不良行为。 每次 Flutter 想要构建该小部件时,都会再次调用该函数。如果这是可取的行为,您可能正在其他地方使用反模式。虽然如果这个小部件位于小部件树的顶部,它可能不会真正产生影响。尽管如此,它还是不受欢迎。


    您的代码对我来说似乎有点奇怪,它可能会被重构为更加清晰和更好,但如果您只是想在转换为 @ 后快速切换到在 initState 中获得未来的正确方法987654328@,您还需要在initState 中访问您的提供者gamesData 值,这可以通过this SO answer 完成。然后将Future 存储在一个变量中,并将该变量传递给您的FutureBuilder

    您应该希望能够使用您在问题中提到的这种模式从示例中弄清楚。如果没有,我可以举个例子。

    【讨论】:

    • 谢谢。我需要一个不需要管理状态的有状态小部件,这对我来说很奇怪,但这是另一个讨论。 :) 谢谢。
    【解决方案2】:

    您也可以在 statefulwidget 中使用相同的方式。在 initstate 中加载 http 数据并不是一个好办法。 还有一件事,使用 statefulwidget 或 statelesswidget 完全取决于您想要实现的输出。所以,你的使用方式是完美的。

    【讨论】:

    • 这是不正确的。使用initState 或类似名称是处理期货的无可争议的正确方法。请参阅my answer,特别是链接和引用的文档。如您所见,initState 被明确提及为获得未来的正确方法,而您在build 中获得未来的建议被明确反对。
    猜你喜欢
    • 1970-01-01
    • 2021-04-28
    • 2022-08-13
    • 2022-01-21
    • 1970-01-01
    • 2020-09-18
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多