-
Notifications
You must be signed in to change notification settings - Fork 220
Description
While working on visgl/deck.gl#9873 I ran into tests failing and runtime errors with luma.gl 9.2 while using React in StrictMode. The resize handler in luma.gl 9.3 has gone through a refactor, so I'm not sure if this issue has already been addressed on master. Opening this issue to investigate further.
Description
A race condition in canvas-context.ts causes TypeError: Cannot read properties of undefined (reading 'maxTextureDimension2D') when using luma.gl with React, particularly in StrictMode.
Stack Trace
canvas-context.ts:238 Uncaught TypeError: Cannot read properties of undefined (reading 'maxTextureDimension2D')
at WebGLCanvasContext.getMaxDrawingBufferSize (canvas-context.ts:238:52)
at WebGLCanvasContext._handleResize (canvas-context.ts:372:62)
at ResizeObserver.<anonymous> (canvas-context.ts:171:65)
Root Cause
The destroy() method in canvas-context.ts only sets this.destroyed = true but does not:
- Disconnect the ResizeObserver
- Disconnect the IntersectionObserver
When React StrictMode unmounts/remounts components, the device gets destroyed but the ResizeObserver callback can still fire, attempting to access this.device.limits.maxTextureDimension2D on a destroyed device.
Affected Code
canvas-context.ts:190-192 - Current destroy() implementation:
destroy() {
this.destroyed = true;
}canvas-context.ts:347 - _handleResize() doesn't check the destroyed flag before accessing device properties.
Suggested Fix
Option 1: Disconnect observers in destroy()
destroy() {
this.destroyed = true;
this._resizeObserver?.disconnect();
this._intersectionObserver?.disconnect();
}Option 2: Add guard in callback
protected _handleResize(entries: ResizeObserverEntry[]) {
if (this.destroyed) return;
// ... rest of logic
}Option 3: Both (most robust)
Reproduction
- Use luma.gl with React in StrictMode
- The double-mount cycle in StrictMode triggers the race condition
- ResizeObserver fires after device destruction
Environment
- luma.gl version: 9.2.x
- React: 18.x with StrictMode enabled
- Browser: Chrome (likely affects all browsers)