在 Flutter 中,当子组件的 build 方法中没有回调时,如何从子组件中读取数据?
Posted
技术标签:
【中文标题】在 Flutter 中,当子组件的 build 方法中没有回调时,如何从子组件中读取数据?【英文标题】:In Flutter, how can I read data from a child widget when callbacks are not available within the build method of the child? 【发布时间】:2020-09-12 16:02:47 【问题描述】:我有一个 AppBar 按钮,我想在其中读取 childData 列表并对其进行处理:
class _ParentState extends State<Parent>
....
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.add),
onPressed: () async
//Need to access childData data here
print(childData); //currently prints null
,
),
],
),
body: SafeArea(
child: Column(
children: <Widget>[
ChildWidget(),
],
ChildWidget 使用 StreamBuilder 并循环遍历快照并在将快照附加到列表之前执行其他操作:
class ChildWidgetState extends State<ChildWidget>
....
Widget build(BuildContext context)
return StreamBuilder<List<DocumentSnapshot>>(
stream: stream,
builder: (context, snapshots)
if (snapshots.connectionState == ConnectionState.active &&
snapshots.hasData)
List<DocumentSnapshot> childData = [];
for (var x in snapshots.data)
//do something else with snapshot data
childData.add(x);
我尝试使用回调函数通知父小部件进行刷新,但这会产生setState() or markNeedsBuild() called during build
错误,因为它在 ChildWidget 的构建方法期间设置状态。我的流构建器中肯定有数据,因为它在其他地方使用,目前没有问题。
像 Provider 这样的状态管理包似乎只向子小部件提供数据,而不是将它们传回,而且我读过使用全局变量是不受欢迎的。将 childData 列表添加到 Hive 之类的数据库包中,然后在我的 ParentWidget 中读取它也是不好的做法吗?我不一定要重建父小部件 - 只需在单击 AppBar 按钮时读取子小部件中的数据。
谢谢。
【问题讨论】:
【参考方案1】:你可以使用provider来获取父widget中的数据
Provider(
create: (_) => MyModel(),
child: ParentWidget()
)
关于 ChildWidget 的使用
data=Provider.of<MyModel>(context);
而MyModel()
可以是数据类,其中包含您希望在父级appBar
中获取的数据。
现在可以在 Steam Builder 中使用
data.childData=newData
然后使用
data=Provider.of<MyModel>(context);
在父小部件和
data.childData
会有你想要的newdata
。
【讨论】:
使用 data=Provider.of(context,listen:false);所以父小部件在数据更改后不会重建以上是关于在 Flutter 中,当子组件的 build 方法中没有回调时,如何从子组件中读取数据?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter PageView组件怎样让子组件不会重复加载
Flutter 功能型组件:跨组件状态共享(Provider)
Vue.js - 当子组件在 <transition> 内时,无法访问 this.$parent
Flutter自定义 Flutter 组件 ( 创建自定义 StatelessWidgetStatefulWidget 组件 | 调用自定义组件 )