如何解决如何在 Flutter 中的页面之间切换时保留 Future 的值?
当未来屏幕 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<Book> placeholder=[];
然后从未来设置值...placeholder=snapshot.data;
在屏幕 1 和 2 之间切换时。我正在检查
placeholder==[]?UserChoiceBooks (title):BookList(title,placeholder)
是否有更好的方法来保持数据从快照中切换屏幕未来值不会丢失?
解决方法
您正在构建期间进行调用:
Provider.of<Books>(context,listen: false).getRecommendedBooks("test")
因此当屏幕重建时,它会再次被调用。您太幸运了,在这两次导航之间没有发生其他重建,因为理论上它们是可能的。
推荐的心态是每帧都可能发生重建,非重建帧应视为框架优化。
所以你应该打一次电话并保存。有几个选项:
-
在树的某处创建
Books
并将其传递给小部件。然后使您的小部件有状态并在其widget.books.getRecommendedBooks
中调用initState()
。 -
如果
Books
是单例,您可以使用 https://pub.dev/packages/get_it 之类的服务定位器将其实例化一次,然后使用GetIt.instance.get
在您的小部件中的任何位置获取此实例。服务定位器模式比提供者模式有一些优势。 -
一种讨厌的方法是在有状态小部件的状态下调用 future 并在第一次构建时调用该方法 if
_future == null
。
对于有状态小部件,请参阅本教程:https://flutter.dev/docs/development/ui/interactive#stateful-and-stateless-widgets
另请注意,您应该将 key
用于此类小部件,对于您传递给构造函数的不同 title
,该小部件会有所不同。否则,当您用另一个 title
替换您的小部件时,框架将不知道接下来的所有内容都是针对另一本书的,并且不会创建新状态,因此不会调用 initState()
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。