Строитель против GlobalKey

Многочисленные вопросы, касающиеся создания пользовательских интерфейсов Flutter, сводятся к неправильному BuildContext (например, показывая SnackBar). Ответы обычно предлагают либо использование Builder или используя GlobalKey, Оба работают, но я заметил, что документация для GlobalKey гласит:

Глобальные ключи относительно дороги. Если вам не нужны какие-либо функции, перечисленные выше, рассмотрите возможность использования Key, ValueKey, ObjectKey, или же UniqueKey вместо.

Упомянутые функции - это уникальная идентификация и переопределение поддерева. Является ли "относительный расход" использования GlobalKey по этим обстоятельствам достаточно оснований, чтобы использовать Builder вместо?

2 ответа

Решение

Настоящая причина, по которой мы склонны избегать GlobalKey не о производительности. Это в большей степени связано с тем, что он нарушает некоторые модели трепетания.

Виджеты по определению не должны иметь доступа к конкретной информации других виджетов (например, их размер или положение). А также GlobalKey предоставить возможность доступа к такой информации; позволяя людям делать анти-шаблонные вещи.

Думать о GlobalKey как средство для выброса реактивного слоя флаттера.

Несколько примеров того, что люди склонны делать, используя GlobalKey:

  • Наличие публичного синглтона GlobalKey, Используется как средство, чтобы не поднимать состояние. Трудно предсказать взаимодействие между виджетами, так как отношения больше не являются односторонними (родитель -> дети становятся двусторонними отношениями)
  • С помощью GlobalKey вычислить размер макета. Затем запустите повторную визуализацию с этой информацией. Это вместо этого роль RenderObject и не должно быть сделано в виджетах. Это делает макет намного сложнее поддерживать

Builder и подобное, с другой стороны, не нарушает эти паттерны. Как по определению Builder ничего не делает Это просто аккуратный способ использования другого BuildContext,

Обычно это означает, что если вы можете решить проблему с макетом, используя Builder вместо GlobalKey, вы на правильном пути к удобному расположению.


Когда использовать GlobalKey затем?

Ну, если сможешь, никогда. Попробуйте вместо этого использовать такие вещи, как context.ancestorStateOfType или же context.inheritWidgetOfExtactType, Вы также можете рассмотреть возможность создания пользовательских RenderObject для конкретного макета. RenderObject в сочетании с parentData также может быть то, что вы хотите, если вам нужны отношения между родителями / детьми

Это может быть сложнее, хотя. Это может занять больше времени, чем вы хотите. Или вы можете попасть в крайний случай, который трудно реализовать с использованием текущего API.

В таких ситуациях это нормально использовать GlobalKey до тех пор, пока вы знаете возможные последствия.

GlobalKey дороговизна, скорее всего, связана с ситуациями, когда вам может понадобиться много ключей, например, для детей ListView,

Я сомневаюсь в стоимости GlobalKey для SnackBar будет иметь значение. Вряд ли вы создадите их много.

Другие вопросы по тегам