我的集团正在产生新的国家。像这样:
yield Loaded(); yield Loaded();
字符串我的BlocListener检索这两个,即使它们是相同的。另一方面,我的BlocBuilder没有。它只会检索第一个(还是最后一个?)一个。我没有使用equatable,我不明白为什么BlocBuilder不会被触发两次。在我的例子中,我只是想再次更新UI,而不实际更改状态。
kzmpq1sx1#
构建小部件是一项昂贵的任务,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不会立即导致重建。setState会立即调用传递给它的闭包,然后将你的widget标记为dirty(以便在下一帧中重建)。这就是为什么多次调用setState只会触发小部件的build方法一次。现在,如果您将该代码中的最后一个setState更改为setState(() => a = 2),则在单击按钮后,您将在控制台中获得2。如果你把它们颠倒过来(首先将a设置为2,然后设置为1),你将在控制台中得到1。现在让我们看看BlocBuilder是如何工作的。BlocBuilder是一个StatefulWidget,它使用BlocListener来更新它的状态,并在需要时重建小部件。下面是它的build方法:
setState
build
setState(() => a = 2)
BlocBuilder
StatefulWidget
BlocListener
@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), ); }
型正如你所看到的,我们在例子中看到的行为也适用于这里,如果你在短时间内重复产生多个状态,它将用最新的状态构建一次。
1条答案
按热度按时间kzmpq1sx1#
构建小部件是一项昂贵的任务,Flutter试图尽可能地减少这一成本。其中之一是防止在状态改变时重复构建。下面是一个例子:
字符串
此示例在第一次生成时打印0。点击按钮后,您应该会看到2个值为1的打印结果,但您将在控制台中只得到一条消息。因为
setState
不会立即导致重建。setState
会立即调用传递给它的闭包,然后将你的widget标记为dirty(以便在下一帧中重建)。这就是为什么多次调用setState
只会触发小部件的build
方法一次。现在,如果您将该代码中的最后一个setState
更改为setState(() => a = 2)
,则在单击按钮后,您将在控制台中获得2。如果你把它们颠倒过来(首先将a设置为2,然后设置为1),你将在控制台中得到1。现在让我们看看BlocBuilder
是如何工作的。BlocBuilder
是一个StatefulWidget
,它使用BlocListener
来更新它的状态,并在需要时重建小部件。下面是它的build
方法:型
正如你所看到的,我们在例子中看到的行为也适用于这里,如果你在短时间内重复产生多个状态,它将用最新的状态构建一次。