生成器与GlobalKey [英] Builder versus GlobalKey
问题描述
有关构建Flutter UI的众多问题归结为错误的BuildContext
(例如显示SnackBar
).答案通常提供使用Builder
还是使用GlobalKey
.两者都有效,但是我注意到 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:
全局密钥相对昂贵.如果不需要上面列出的任何功能,请考虑使用
Key
,ValueKey
,ObjectKey
或UniqueKey
.
所指的功能是唯一的标识和子树重新成对.在这种情况下使用GlobalKey
的相对费用"是否足以代替使用Builder
?
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?
推荐答案
我们倾向于避免GlobalKey
的真正原因与性能无关.与此有关的是,它会打乱一些图案.
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.
按定义,小部件不应能够访问其他小部件的具体信息(例如它们的大小或位置).并且GlobalKey
授予访问此类信息的能力;允许人们做反模式的东西.
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.
将GlobalKey
视为平均值,以弹出 Flutter的反应层.
Think of GlobalKey
as a mean to eject the reactive layer of Flutter.
使用GlobalKey
诱使人们做什么的一些示例:
A few examples of what peoples are tempted to do using GlobalKey
:
- 具有公共单例
GlobalKey
.用作不提升状态的一种手段.由于关系不再是单边的,使得小部件之间的交互变得难以预测(父母->孩子变成了双向关系) - 使用
GlobalKey
计算布局的大小.然后使用此信息触发重新渲染.相反,这是RenderObject
的角色,不应在小部件中完成.这使得布局难以维护
- 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
不会破坏这些模式.因此,根据定义,Builder
什么都不做.这只是使用其他BuildContext
的一种巧妙方法.
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
.
这通常意味着,如果您可以使用Builder
而不是GlobalKey
解决布局问题,那么您将走上可维护布局的正确之路.
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.
那么什么时候使用GlobalKey
?
好吧,如果可以的话,永远不要.尝试改用context.ancestorStateOfType
或context.inheritWidgetOfExtactType
之类的东西.您可能还需要考虑为特定布局创建自定义RenderObject
.如果需要父母/孩子之间的关系,将RenderObject
与parentData
结合使用也可能是您想要的
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
这可能更复杂.它可能消耗比您想要的更多的时间.否则,您可能会陷入难以使用当前API实施的局面.
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.
在这种情况下,只要您知道潜在的后果,就可以使用GlobalKey
.
In such situations, it is ok to use GlobalKey
as long as you know the potential consequences.
这篇关于生成器与GlobalKey的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!