Система управления состоянием в Deck.gl строится вокруг идеи
однонаправленного потока данных: состояние описывается
как набор входных параметров, а визуализация является функцией этого
состояния. Основной источник истины — объект Deck и массив
слоёв (layers), передаваемый при каждом обновлении.
Ключевые элементы состояния:
DeckviewState)Layer state)В отличие от классических UI-фреймворков, Deck.gl минимизирует внутреннее изменяемое состояние слоёв, предпочитая пересборку вычисляемых параметров при изменении входных данных.
Обновление сцены в Deck.gl основано на сравнении ссылок, а не глубоких структурных проверках. Это означает:
layers должен создаваться заново при
измененияхviewState рассматриваются как неизменяемыеПример базовой модели:
const deck = new Deck({
initialViewState: {
longitude: 0,
latitude: 0,
zoom: 3
},
controller: true,
layers: []
});
Обновление состояния:
deck.setProps({
viewState: {
longitude: 10,
latitude: 50,
zoom: 5
},
layers: newLayers
});
Ключевая особенность: Deck.gl не модифицирует существующие объекты, а заменяет их целиком.
viewState представляет собой состояние камеры и является
центральной частью реактивной модели.
Основные свойства:
longitude, latitudezoompitch, bearingconst onViewStateCha nge = ({ viewState }) => {
deck.setProps({ viewState });
};
В этом режиме внешний код полностью управляет камерой.
При использовании встроенного контроллера:
new Deck({
controller: true,
initialViewState: {...}
});
Deck.gl самостоятельно обновляет viewState, но может
уведомлять приложение через onViewStateChange.
Массив layers — основной источник визуального состояния.
Deck.gl применяет диффинг:
id слояПример:
const layers = [
new ScatterplotLayer({
id: 'points',
data,
getPosition: d => d.position,
getRadius: 100
})
];
Изменение данных:
const updatedLayers = [
new ScatterplotLayer({
id: 'points',
data: newData,
getPosition: d => d.position,
getRadius: 120
})
];
Даже при создании нового объекта слоя, Deck.gl может переиспользовать
GPU-атрибуты при совпадении id.
Одним из ключевых механизмов оптимизации состояния является
updateTriggers. Он позволяет контролировать, когда
пересчитываются атрибуты слоя.
new ScatterplotLayer({
id: 'points',
data,
getPosition: d => d.position,
getRadius: d => d.size,
updateTriggers: {
getRadius: dataVersion
}
});
Поведение:
dataVersion не изменился — атрибуты не
пересчитываютсяЭто критически важно для больших наборов данных.
Каждый слой в Deck.gl имеет собственное внутреннее состояние:
AttributeManager)Это состояние не хранится в пользовательских объектах и управляется жизненным циклом слоя:
initializeStateupdateStatefinalizeStateПример логики обновления:
updateState({ props, oldProps, changeFlags }) {
if (changeFlags.dataChanged) {
this._updateAttributes();
}
}
Deck.gl использует модель, близкую к React:
Типичная структура:
new LineLayer({
id: 'lines',
data,
getSourcePosition,
getTargetPosition,
opacity: 0.8
});
Изменение opacity не требует пересоздания буферов, но изменение
функций доступа (get*) может их триггерить.
Состояние взаимодействия формируется через систему picking:
Обработчик:
onHover: info => {
const { object, x, y } = info;
}
info содержит:
object — выбранный элементcoordinate — географические координатыpixel — экранные координатыlayer — источник событияЭто состояние обычно не хранится внутри Deck.gl, а выносится в внешнее приложение.
Типичная схема:
const [hoverInfo, setHoverInfo] = useState(null);
const layers = [
new ScatterplotLayer({
id: 'points',
data,
pickable: true,
onHover: setHoverInfo
})
];
Такое разделение позволяет:
При использовании React состояние становится частью props-композиции:
<DeckGL
viewState={viewState}
layers={layers}
onViewStateCha nge={setViewState}
controller={true}
/>
Особенности:
viewState полностью контролируемыйlayers пересоздаются при каждом изменении данныхКритический момент — стабильность ссылок:
const layers = useMemo(() => [
new ScatterplotLayer({ ... })
], [data]);
Без мемоизации создаётся избыточная пересборка слоёв.
Архитектурно состояние делится на два слоя:
Внешнее состояние приложения:
Внутреннее состояние Deck.gl:
Разделение важно для масштабируемости: внешнее состояние управляется приложением, внутреннее — самим движком.
Deck.gl поддерживает анимированные изменения состояния:
new ScatterplotLayer({
id: 'points',
data,
getRadius: 100,
transitions: {
getRadius: 500
}
});
Особенности:
Если включён controller: true, появляется дополнительный
слой состояния:
new Deck({
controller: {
inertia: true,
scrollZoom: { speed: 0.01 },
dragRotate: true
}
});
Это состояние не связано с данными слоёв, но влияет на
viewState.
При одновременном управлении камерой возможны конфликты:
initialViewState используется только один разviewState (если задан) имеет приоритетПриоритетная схема:
viewStateonViewStateChangeDeck.gl активно использует кэш:
Ключевая идея: минимизация пересчёта при неизменном состоянии.
Пример влияния:
При наличии большого количества слоёв управление состоянием становится иерархическим:
Каждый уровень может иметь собственные updateTriggers,
что позволяет локализовать пересчёты.
viewState вместо замены объектаid у слоёвsetPropsЭти ошибки приводят к деградации производительности и потере кэширования.
Deck.gl часто интегрируется с внешними системами состояния:
Типовая схема:
viewState и фильтрыЭто обеспечивает строгую синхронизацию UI и визуализации без расхождений состояния.