Builder 与 GlobalKey [英] Builder versus GlobalKey

查看:27
本文介绍了Builder 与 GlobalKey的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

许多与构建 Flutter UI 相关的问题都归结为错误的 BuildContext(例如显示 SnackBar).答案通常是使用 Builder 或使用 GlobalKey.两者都有效,但我注意到 GlobalKey 的文档指出:<块引用>

全局密钥相对昂贵.如果您不需要上面列出的任何功能,请考虑使用 KeyValueKeyObjectKeyUniqueKey代替.

所指的特征是唯一标识和子树重新父子关系.在这些情况下使用 GlobalKey 的相对费用"是否足以代替使用 Builder?

解决方案

我们倾向于避免 GlobalKey 的真正原因与性能无关.更相关的是它在flutter中打破了一些模式.

根据定义,小部件不应该能够访问其他小部件的具体信息(例如它们的大小或位置).并且 GlobalKey 授予访问此类信息的能力;允许人们做反模式的事情.

GlobalKey 视为弹出 Flutter 反应层的一种手段.

人们想要使用 GlobalKey 做什么的几个例子:

  • 有一个公共单例GlobalKey.用作不提升状态的手段.使小部件之间的交互难以预测,因为这种关系不再是片面的(父母 -> 孩子成为双向关系)
  • 使用 GlobalKey 计算布局的大小.然后使用此信息触发重新渲染.这是 RenderObject 的作用,不应在小部件中完成.它使布局更难维护
<小时>

Builder 和另一方面的类似内容不会破坏这些模式.因为,根据定义,Builder 什么都不做.这只是使用不同 BuildContext 的一种巧妙方式.

这通常意味着,如果您可以使用 Builder 而不是 GlobalKey 来解决布局问题,那么您就走上了可维护布局的正确轨道.

<小时>

什么时候使用GlobalKey?

好吧,如果可以,永远不要.尝试使用诸如 context.ancestorStateOfTypecontext.inheritWidgetOfExtactType 之类的东西.您可能还需要考虑为特定布局创建自定义 RenderObject.如果您需要父/子之间的关系,RenderObjectparentData 结合也可能是您想要的

虽然这可能更复杂.它可能会消耗比您想要的更多的时间.或者,您可能会陷入使用当前 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, or UniqueKey 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 of RenderObject 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆