React Components for deck.gl that provide WebGL2-powered data visualization capabilities within React applications
npx @tessl/cli install tessl/npm-deck-gl--react@8.9.0React Components for deck.gl that provide WebGL2-powered data visualization capabilities within React applications. This package offers a DeckGL React component that serves as a wrapper around deck.gl's core functionality, enabling developers to create high-performance, large-scale data visualizations within React apps.
npm install @deck.gl/reactimport DeckGL from "@deck.gl/react";
// or
import { DeckGL } from "@deck.gl/react";
// Import types
import type { DeckGLProps, DeckGLRef, DeckGLContextValue } from "@deck.gl/react";For CommonJS:
const DeckGL = require("@deck.gl/react");
// or
const { DeckGL } = require("@deck.gl/react");import React from "react";
import DeckGL from "@deck.gl/react";
import { ScatterplotLayer } from "@deck.gl/layers";
const INITIAL_VIEW_STATE = {
longitude: -122.4,
latitude: 37.8,
zoom: 11,
pitch: 0,
bearing: 0
};
function App() {
const layers = [
new ScatterplotLayer({
id: "scatterplot-layer",
data: [
{ position: [-122.4, 37.8], color: [255, 0, 0] },
{ position: [-122.45, 37.85], color: [0, 255, 0] },
],
getPosition: (d) => d.position,
getFillColor: (d) => d.color,
getRadius: 100,
}),
];
return (
<DeckGL
initialViewState={INITIAL_VIEW_STATE}
controller={true}
layers={layers}
width="100vw"
height="100vh"
/>
);
}
// JSX Layer Syntax (alternative to layers prop)
function AppWithJSX() {
return (
<DeckGL
initialViewState={INITIAL_VIEW_STATE}
controller={true}
width="100vw"
height="100vh"
>
<ScatterplotLayer
id="scatterplot-layer"
data={[
{ position: [-122.4, 37.8], color: [255, 0, 0] },
{ position: [-122.45, 37.85], color: [0, 255, 0] },
]}
getPosition={(d) => d.position}
getFillColor={(d) => d.color}
getRadius={100}
/>
</DeckGL>
);
}@deck.gl/react is built around several key components:
The main React component that wraps deck.gl's Deck class, providing full React integration with declarative props and lifecycle management.
/**
* Main React component for deck.gl integration
* Provides React wrapper around deck.gl's Deck class with full lifecycle management
*/
const DeckGL: React.ForwardRefExoticComponent<
DeckGLProps & React.RefAttributes<DeckGLRef>
>;
interface DeckGLProps extends Omit<DeckProps, 'width' | 'height' | 'gl' | 'parent' | 'canvas' | '_customRender'> {
/** Custom Deck class to use instead of default */
Deck?: typeof Deck;
/** Component width (CSS value) */
width?: string | number;
/** Component height (CSS value) */
height?: string | number;
/** Child components or render callback function */
children?: React.ReactNode | ((args: {x: number, y: number, width: number, height: number, viewState: any, viewport: Viewport}) => React.ReactNode);
/** Context provider for child components */
ContextProvider?: React.Context<DeckGLContextValue>['Provider'];
}
interface DeckGLRef {
/** Access to underlying Deck instance */
deck?: Deck;
/** Pick object at coordinate */
pickObject: Deck['pickObject'];
/** Pick multiple objects */
pickObjects: Deck['pickObjects'];
/** Pick objects with multi-picking support */
pickMultipleObjects: Deck['pickMultipleObjects'];
}Usage Examples:
import React, { useRef } from "react";
import DeckGL, { DeckGLRef } from "@deck.gl/react";
// Basic usage with layers
function BasicMap() {
return (
<DeckGL
initialViewState={{
longitude: -122.4,
latitude: 37.8,
zoom: 11
}}
controller={true}
layers={[/* your layers */]}
/>
);
}
// With ref for imperative API access
function MapWithRef() {
const deckRef = useRef<DeckGLRef>(null);
const handleClick = (event: React.MouseEvent) => {
if (deckRef.current) {
const picked = deckRef.current.pickObject({
x: event.clientX,
y: event.clientY
});
console.log("Picked object:", picked);
}
};
return (
<div onClick={handleClick}>
<DeckGL
ref={deckRef}
initialViewState={{ longitude: 0, latitude: 0, zoom: 1 }}
controller={true}
layers={[/* your layers */]}
/>
</div>
);
}
// With children components
function MapWithChildren() {
return (
<DeckGL
initialViewState={{ longitude: 0, latitude: 0, zoom: 1 }}
controller={true}
layers={[/* your layers */]}
>
<div style={{ position: 'absolute', top: 10, left: 10 }}>
<h3>Map Controls</h3>
</div>
</DeckGL>
);
}
// With render callback
function MapWithCallback() {
return (
<DeckGL
initialViewState={{ longitude: 0, latitude: 0, zoom: 1 }}
controller={true}
layers={[/* your layers */]}
>
{({ viewport, viewState }) => (
<div style={{ position: 'absolute', top: 10, left: 10 }}>
<p>Longitude: {viewState.longitude.toFixed(2)}</p>
<p>Latitude: {viewState.latitude.toFixed(2)}</p>
<p>Zoom: {viewState.zoom.toFixed(1)}</p>
</div>
)}
</DeckGL>
);
}Context value type for integrating child components with deck.gl's view system.
/**
* Context value provided to child components
* Contains viewport information and event handlers for deck.gl integration
*/
interface DeckGLContextValue {
/** Current viewport instance */
viewport: Viewport;
/** DOM container element */
container: HTMLElement;
/** Event management instance */
eventManager: EventManager;
/** View state change callback */
onViewStateChange: DeckProps['onViewStateChange'];
}The DeckGL component supports render callback functions as children, which receive viewport information for dynamic content rendering. The callback function signature is not exported as a public type but follows this internal pattern:
Usage Example:
import DeckGL from "@deck.gl/react";
// Render callback receives viewport information
const renderCallback = ({ viewState, viewport }) => {
return (
<div style={{
position: 'absolute',
top: 10,
left: 10,
background: 'rgba(0,0,0,0.8)',
color: 'white',
padding: '10px',
borderRadius: '4px'
}}>
<h4>Current View</h4>
<p>Zoom: {viewState.zoom.toFixed(1)}</p>
<p>Center: [{viewState.longitude.toFixed(3)}, {viewState.latitude.toFixed(3)}]</p>
<p>Viewport Size: {viewport.width}x{viewport.height}</p>
</div>
);
};
function MapWithInfo() {
return (
<DeckGL
initialViewState={{ longitude: 0, latitude: 0, zoom: 1 }}
controller={true}
layers={[]}
>
{renderCallback}
</DeckGL>
);
}// Re-exported from @deck.gl/core for convenience
type DeckProps = import('@deck.gl/core').DeckProps;
type Viewport = import('@deck.gl/core').Viewport;
type Deck = import('@deck.gl/core').Deck;
type EventManager = import('mjolnir.js').EventManager;The DeckGL component handles common error scenarios:
Common Error Patterns:
// Handle WebGL context loss
function RobustMap() {
const handleContextLoss = () => {
console.warn("WebGL context lost, reinitializing...");
};
return (
<DeckGL
onWebGLInitialized={(gl) => {
gl.getExtension('WEBGL_lose_context')?.addEventListener('contextlost', handleContextLoss);
}}
// ... other props
/>
);
}
// Handle layer errors
function SafeMap() {
const handleError = (error: Error) => {
console.error("Deck.gl error:", error);
// Handle error appropriately
};
return (
<DeckGL
onError={handleError}
// ... other props
/>
);
}The DeckGL component integrates seamlessly with popular React map libraries:
// With react-map-gl
import DeckGL from "@deck.gl/react";
import { Map } from "react-map-gl";
function MapWithBasemap() {
return (
<DeckGL
initialViewState={{
longitude: -122.4,
latitude: 37.8,
zoom: 11
}}
controller={true}
layers={[/* layers */]}
>
<Map
mapStyle="mapbox://styles/mapbox/light-v9"
mapboxAccessToken="your-token"
/>
</DeckGL>
);
}// Optimized layer updates
function OptimizedMap({ data }: { data: any[] }) {
const layers = useMemo(
() => [
new ScatterplotLayer({
id: 'points',
data,
getPosition: (d) => d.coordinates,
getRadius: 100,
}),
],
[data] // Only recreate when data changes
);
return (
<DeckGL
initialViewState={{ longitude: 0, latitude: 0, zoom: 1 }}
controller={true}
layers={layers}
/>
);
}