Строитель против 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
будет иметь значение. Вряд ли вы создадите их много.