【问题标题】:How to persist value from a Future when switching between pages in Flutter?在 Flutter 中的页面之间切换时如何保持 Future 的值?
【发布时间】:2021-03-26 17:03:20
【问题描述】:

当未来在屏幕 1 中有数据时,我正在尝试向屏幕添加一个小部件。

class UserChoiceBooks extends StatelessWidget {
  final String title;
  UserChoiceBooks({Key key, this.title}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: Provider.of<Books>(context, listen: false)
            .getRecommendedBooks("test"),
        builder: (ctx, snapshot) {
          // Checking if future is resolved
          if (snapshot.connectionState == ConnectionState.done) {
            // If we got an error
            if (snapshot.hasError) {
              return Center(
                child: Text(
                  '${snapshot.error} occured',
                  style: TextStyle(fontSize: 18),
                ),
              );
              // if we got our data
            } else if (snapshot.hasData) {
              // Extracting data from snapshot object
              final List<Book> recommendedBooksML = snapshot.data;
              return BookList(title, recommendedBooksML);
            } else {
              return SizedBox.shrink();
            }
          } else {
            return Container();
          }
        }
        //  ... some code here
        );
  }
}

我导航到另一个屏幕屏幕 2。 然后回到屏幕 1。我释放了未来的数据,它再次开始构建。

PS:我通过将 Future 数据存储在全局变量中找到了一个临时解决方法 List&lt;Book&gt; placeholder=[];

然后设置未来的值...placeholder=snapshot.data;

在屏幕 1 和 2 之间切换时。我正在检查 placeholder==[]?UserChoiceBooks (title):BookList(title,placeholder)

有没有一种更好的方法来保存数据,以便在屏幕未来值之间切换不会丢失?

【问题讨论】:

    标签: flutter flutter-futurebuilder


    【解决方案1】:

    您正在构建期间拨打电话:

    Provider.of<Books>(context, listen: false).getRecommendedBooks("test")
    

    因此,当屏幕重建时,它会再次被调用。你太幸运了,这两个导航之间没有发生其他重建,因为理论上它们是可能的。

    建议的思维方式是在每一帧都可能发生重建,非重建帧应被视为框架优化。

    所以你应该打一次电话并保存它。有几个选项:

    1. 在树的某处创建Books 并将其传递给小部件。然后使您的小部件有状态并在其initState() 中调用widget.books.getRecommendedBooks

    2. 如果Books 是单例,您可以使用https://pub.dev/packages/get_it 之类的服务定位器将其实例化一次,然后使用GetIt.instance.get 在您的小部件中的任何位置获取此实例。服务定位器模式比提供者模式有一些优势。

    3. 一种讨厌的方法是在有状态小部件的状态下调用未来,并在首次构建时调用该方法,如果 _future == null

    有关有状态小部件,请参阅本教程:https://flutter.dev/docs/development/ui/interactive#stateful-and-stateless-widgets

    还请注意,您应该为这样的小部件使用key,这对于您传递给构造函数的不同titles 会有所不同。否则,当您将您的小部件替换为另一个 title 时,框架将不知道接下来的所有内容都是针对另一本书的,并且不会创建新状态,因此不会调用 initState()

    【讨论】:

    • 初始化状态不带上下文。所以我不能打电话给Provider.of&lt;Books&gt;(context, listen: false).getRecommendedBooks("test")。我尝试使用 didChangeDependencies。将future添加到Init状态会阻止页面加载直到它完成?
    • 谢谢,这让我无法理解。我添加了 3 个其他解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-08-22
    • 2020-06-30
    • 2018-09-13
    • 2015-12-12
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    相关资源
    最近更新 更多