Builder 与 GlobalKey [英] Builder versus GlobalKey
问题描述
许多与构建 Flutter UI 相关的问题都归结为错误的 BuildContext
(例如显示 SnackBar
).答案通常是使用 Builder
或使用 GlobalKey
.两者都有效,但我注意到 GlobalKey 的文档指出:><块引用>
全局密钥相对昂贵.如果您不需要上面列出的任何功能,请考虑使用 Key
、ValueKey
、ObjectKey
或 UniqueKey代码>代替.
所指的特征是唯一标识和子树重新父子关系.在这些情况下使用 GlobalKey
的相对费用"是否足以代替使用 Builder
?
我们倾向于避免 GlobalKey
的真正原因与性能无关.更相关的是它在flutter中打破了一些模式.
根据定义,小部件不应该能够访问其他小部件的具体信息(例如它们的大小或位置).并且 GlobalKey
授予访问此类信息的能力;允许人们做反模式的事情.
将GlobalKey
视为弹出 Flutter 反应层的一种手段.
人们想要使用 GlobalKey
做什么的几个例子:
- 有一个公共单例
GlobalKey
.用作不提升状态的手段.使小部件之间的交互难以预测,因为这种关系不再是片面的(父母 -> 孩子成为双向关系) - 使用
GlobalKey
计算布局的大小.然后使用此信息触发重新渲染.这是RenderObject
的作用,不应在小部件中完成.它使布局更难维护
Builder
和另一方面的类似内容不会破坏这些模式.因为,根据定义,Builder
什么都不做.这只是使用不同 BuildContext
的一种巧妙方式.
这通常意味着,如果您可以使用 Builder
而不是 GlobalKey
来解决布局问题,那么您就走上了可维护布局的正确轨道.
什么时候使用GlobalKey
?
好吧,如果可以,永远不要.尝试使用诸如 context.ancestorStateOfType
或 context.inheritWidgetOfExtactType
之类的东西.您可能还需要考虑为特定布局创建自定义 RenderObject
.如果您需要父/子之间的关系,RenderObject
与 parentData
结合也可能是您想要的
虽然这可能更复杂.它可能会消耗比您想要的更多的时间.或者,您可能会陷入使用当前 API 难以实现的边缘情况.
在这种情况下,只要您知道潜在的后果,就可以使用 GlobalKey
.
Numerous questions relating to building Flutter UIs come down to the wrong BuildContext
(such as showing a SnackBar
). The answers usually offer either of using a Builder
or using a GlobalKey
. Both work, but I noticed that the documentation for GlobalKey states:
Global keys are relatively expensive. If you don't need any of the features listed above, consider using a
Key
,ValueKey
,ObjectKey
, orUniqueKey
instead.
The features referred to are unique identification and subtree re-parenting. Is the "relative expense" of using a GlobalKey
for these circumstances reason enough to use a Builder
instead?
The real reason we tend to avoid GlobalKey
is not about performance. It is more related to the fact that it breaks a few patterns in flutter.
Widgets by definition should not be able to access concrete information of other widgets (such as their size or position). And GlobalKey
grant the ability to access such information; allowing peoples to do anti-pattern stuff.
Think of GlobalKey
as a mean to eject the reactive layer of Flutter.
A few examples of what peoples are tempted to do using GlobalKey
:
- Having a public singleton
GlobalKey
. Used as a mean to not lift the state up. Making interaction between widgets hard to predict, as the relationship isn't one-sided anymore (parent -> children becomes a two-way relationship) - Using
GlobalKey
to compute the size of a layout. Then trigger a re-render with this information. This instead is the role ofRenderObject
and shouldn't be done in widgets. It makes layout much harder to maintain
Builder
and similar on the other hand don't break these patterns. As, by definition Builder
does nothing. It's just a neat way of using a different BuildContext
.
This usually means that if you can solve your layout problem using Builder
instead of GlobalKey
, you're on the right track to a maintainable layout.
When to use GlobalKey
then?
Well, if you can, never. Try to instead use things such as context.ancestorStateOfType
or context.inheritWidgetOfExtactType
. You may also want to consider creating a custom RenderObject
for a specific layout. RenderObject
combined with parentData
may also be what you want if you need a relationship between parent/children
This can more complicated though. It can consume more time than you want. Or you may fall into an edge-case that is hard to implement using the current API.
In such situations, it is ok to use GlobalKey
as long as you know the potential consequences.
这篇关于Builder 与 GlobalKey的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!