繁体   English   中英

如何防止 FutureBuilder 的重建,即使其潜在的未来没有改变

[英]How to prevent FutureBuilder's rebuilds even its underlying future does not change

在 Flutter 中,我得到了不需要的重建。 在我的例子中,我使用 FutureBuilder 通过获取数据库结果来显示列表,这是一个未来并且依赖于查询参数。 我试图让 FutureBuilder 的未来在查询参数不变的情况下也不会改变,但每次仍然调用 FutureBuilder 的构建器块。 我怎样才能让 FutureBuilder 不会在它的未来不会改变的地方重建自己。

下面是我的代码,每次构建 MusicList2 的父小部件时,MusicList2 都会重建,其 FutureBuilder 也会重建。

class MusicList2 extends StatefulWidget {
  final MusicRowActionCallback onTapItem;
  final MusicRowActionCallback onDoubleTap;
  final MusicRowActionCallback onLongPressed;
  final String facetName;
  final String facetValue;
  const MusicList2(
      {Key key,
        this.onTapItem,
        this.onDoubleTap,
        this.onLongPressed,
        this.facetName,
        this.facetValue}) : super(key: key);
  @override
  State<StatefulWidget> createState() {

    return _MusicList2State();
  }


}

class _MusicList2State extends State<MusicList2> {
  Future<List<Music>> loadMusicByFacet;
  @override
  Widget build(BuildContext context) {

    return FutureBuilder<List<Music>>(
      future:
        loadMusicByFacet,
      builder: (context, snapshot) {
        if (snapshot.data == null)
          return Center(child: CircularProgressIndicator(),);
        return ListView.builder(
          shrinkWrap: true,
          key: const ValueKey<String>('music-list'),
          itemCount: snapshot.data.length,
          itemBuilder: (BuildContext context, int index) {
            final random = Random();
            var i = random.nextInt(5);
            return MusicRow(
              avatarBgColor: colors[i],
              music: snapshot.data[index],
              onTap: widget.onTapItem,
              onDoubleTap: widget.onDoubleTap,
              onLongPressed: widget.onLongPressed,
            );
          },
        );
      },
    );
  }

  @override
  void initState() {
    super.initState();
    loadMusicByFacet = MusicsDatabaseRepository.get.getMusicsByFacet(widget.facetName, widget.facetValue);
  }
  @override
  void didUpdateWidget(MusicList2 oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.facetValue != widget.facetValue || oldWidget.facetName != widget.facetName) {
      loadMusicByFacet = MusicsDatabaseRepository.get.getMusicsByFacet(widget.facetName, widget.facetValue);
    }
  }
}

对于遇到此错误的任何其他人,我使用 GitHub 上的AbdulRahmanAlHamali解决方案解决了这个问题。 这是他的回答:

您好,我认为这里的问题是每次发出重建时都会调用 FutureBuilder 状态的 didUpdateWidget。 此函数检查旧的未来对象是否与新的不同,如果不同,则重新启动 FutureBuilder。

为了解决这个问题,我们可以在构建函数之外的其他地方调用 Future。 例如,在initState中,将其保存在一个成员变量中,并将这个变量传递给FutureBuilder。

因此,与其拥有:

 FutureBuilder( future: someFunction(), ....

我们本应该:

 initState() { super.initState(); _future = SomeFunction(); }

接着

FutureBuilder( future: _future, ....

这里找到原始线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM