【发布时间】:2021-10-06 20:06:00
【问题描述】:
对于发布伪代码提前致歉。真正的代码会太长。
我有一个屏幕,顶部有一个下拉菜单,用户可以在其中选择一个选项。页面的其余部分将根据该选项进行更新。像这样的:
// state variable
String idFromDropdown;
Column(
children: [
DropDownWidget(),
ChildWidget1(myId: idFromDropDown),
ChildWidget2(myId: idFromDropDown),
ChildWidget3(myId: idFromDropDown),
]
)
在子小部件中,我使用 widget.myId 传递到后端服务并读取新数据。
期望是当下拉列表更改并且我调用时
setState((val)=>{idFromDropdown = val});
然后该值将级联到三个子小部件中。根据 widget.myId 的新值,以某种方式触发小部件重新连接到后端服务。
如何触发子小部件的状态更新?
我最终使用了 ValueNotifier。而不是直接使用字符串并将其传递给子小部件。我最终做了类似的事情:
ValueNotifier<String> idFromDropdown;
...
setState((val)=>{idFromDropdown.value = val});
然后在每个小部件中,我将一个侦听器添加到传入的 ValueNotifier 并重新触发对后端服务的读取。
虽然这可行,但我觉得我错过了一些明显的东西。我的 childwidgets 现在接受一个 ValueNotifier 而不是一个值。恐怕这会让我的 ChildWidgets 在其他情况下更难使用。
这是正确的做法吗?
【问题讨论】:
-
我正在测试这个,它在没有
ValueNotifier的情况下工作。如果setState()内部的值发生变化,则在父小部件上,它也会调用它;要构建的子级。像这里,dropDown 值在父节点上更新,子节点取决于idFromDropdown,如果你像这样通过,子节点将在这里重建。我刚刚测试了它来回答这个问题,如果你希望我可以在回答时分享它。 -
问题是,即使状态发生变化,我真正需要做的是在孩子中触发某种“loadData(myID)”函数来获取新数据。在第一次创建时,我从 initState() 调用这个函数来获取数据。现在当 idFromDropdown 的值发生变化时,我不知道如何用新的 id 触发 loadData(myId)。我在颤振中找不到“onStateChange”类型的回调。
-
你在 childWidget 上使用
futureBuilder吗? -
是的。基本上在子小部件中,我从 initstate 调用 loadData。这将返回一个未来。然后在 build 方法中,有一个 future builder 来创建 UI。我需要一种重新触发 loadData 的方法。这将使我能够创造一个新的未来,由未来的建设者接手。
-
让状态管理来处理