新状态不调用 Flutter BlocBuilder
Flutter BlocBuilder is not called for new states
我的集团正在产生新的状态,例如像这样:
yield Loaded();
yield Loaded();
我的 BlocListener 检索这两个,即使它们是相同的。
另一方面,我的 BlocBuilder 没有。它只会检索第一个(或最后一个?)。
我没有使用 equatable,我不明白为什么两次都不会触发 BlocBuilder。
在我的例子中,我只是想再次更新 UI,而不实际更改状态。
构建小部件是一项代价高昂的任务,Flutter 会尽可能地降低这种成本。其中之一是在状态改变时防止重复构建。这是一个例子:
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
int a = 0;
@override
Widget build(BuildContext context) {
print(a);
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: () {
setState(() => a = 1);
setState(() => a = 1);
}),
);
}
}
此示例在第一次构建时打印 0。单击该按钮后,您应该会打印 2 个值为 1 的打印件,但您只会在控制台中收到一条消息。为什么?因为 setState
是一个 async
函数,当它们被重复调用或在一小部分时间内被调用时,Flutter 会将它们批处理在一起,并且只触发一次构建。现在,如果您将该代码中的最后一个 setState
更改为 setState(() => a = 2)
,您将在单击按钮后在控制台中获得 2。如果你反转它们(首先将 a 设置为 2,然后设置为 1),你将在控制台中得到 1。考虑到这一点,让我们看看 BlocBuilder
是如何工作的?
BlocBuilder
是一个 StatefulWidget
并使用 BlocListener
更新它的状态并在需要时重建小部件。这是 build
方法:
@override
Widget build(BuildContext context) {
return BlocListener<C, S>(
cubit: _cubit,
listenWhen: widget.buildWhen,
listener: (context, state) => setState(() => _state = state),
child: widget.build(context, _state),
);
}
如您所见,我们在示例中看到的相同逻辑也适用于此,如果您在短时间内重复产生多个状态,它将使用最新状态构建一次。
我的集团正在产生新的状态,例如像这样:
yield Loaded();
yield Loaded();
我的 BlocListener 检索这两个,即使它们是相同的。
另一方面,我的 BlocBuilder 没有。它只会检索第一个(或最后一个?)。
我没有使用 equatable,我不明白为什么两次都不会触发 BlocBuilder。
在我的例子中,我只是想再次更新 UI,而不实际更改状态。
构建小部件是一项代价高昂的任务,Flutter 会尽可能地降低这种成本。其中之一是在状态改变时防止重复构建。这是一个例子:
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
int a = 0;
@override
Widget build(BuildContext context) {
print(a);
return Scaffold(
floatingActionButton: FloatingActionButton(onPressed: () {
setState(() => a = 1);
setState(() => a = 1);
}),
);
}
}
此示例在第一次构建时打印 0。单击该按钮后,您应该会打印 2 个值为 1 的打印件,但您只会在控制台中收到一条消息。为什么?因为 setState
是一个 async
函数,当它们被重复调用或在一小部分时间内被调用时,Flutter 会将它们批处理在一起,并且只触发一次构建。现在,如果您将该代码中的最后一个 setState
更改为 setState(() => a = 2)
,您将在单击按钮后在控制台中获得 2。如果你反转它们(首先将 a 设置为 2,然后设置为 1),你将在控制台中得到 1。考虑到这一点,让我们看看 BlocBuilder
是如何工作的?
BlocBuilder
是一个 StatefulWidget
并使用 BlocListener
更新它的状态并在需要时重建小部件。这是 build
方法:
@override
Widget build(BuildContext context) {
return BlocListener<C, S>(
cubit: _cubit,
listenWhen: widget.buildWhen,
listener: (context, state) => setState(() => _state = state),
child: widget.build(context, _state),
);
}
如您所见,我们在示例中看到的相同逻辑也适用于此,如果您在短时间内重复产生多个状态,它将使用最新状态构建一次。