Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion modules/react/src/utils/use-widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function useWidget<WidgetT extends Widget, WidgetPropsT extends WidgetPro
return () => {
// Remove widget from context when it is unmounted
const index = widgets?.indexOf(widget);
if (index && index !== -1) {
if (index !== -1) {
widgets?.splice(index, 1);
deck?.setProps({widgets});
}
Expand Down
66 changes: 64 additions & 2 deletions test/modules/react/deckgl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

/* eslint-disable no-unused-vars */
import test from 'tape-promise/tape';
import {createElement, createRef} from 'react';
import {StrictMode, createElement, createRef} from 'react';
import {createRoot} from 'react-dom/client';
import {act} from 'react-dom/test-utils';

import {DeckGL, Layer, Widget} from 'deck.gl';
import {DeckGL, Layer, Widget, useWidget} from 'deck.gl';
import {type WidgetProps, type WidgetPlacement} from '@deck.gl/core';

import {gl} from '@deck.gl/test-utils';
Expand Down Expand Up @@ -163,3 +163,65 @@ test('DeckGL#props omitted are reset', t => {
});
t.ok(ref.current, 'DeckGL overlay is rendered.');
});

class StrictModeWidget extends Widget<WidgetProps> {
placement: WidgetPlacement = 'top-left';
className = 'deck-strict-mode-widget';

constructor(props: WidgetProps = {}) {
super(props, Widget.defaultProps);
}

onRenderHTML(rootElement: HTMLElement): void {}
}

const StrictModeWidgetComponent = (props: WidgetProps) => {
useWidget(StrictModeWidget, props);
return null;
};

test('useWidget#StrictMode cleanup removes duplicate widgets', t => {
const ref = createRef();
const container = document.createElement('div');
document.body.append(container);
const root = createRoot(container);
let onLoadCalled = false;

act(() => {
root.render(
createElement(
StrictMode,
null,
createElement(
DeckGL,
{
initialViewState: TEST_VIEW_STATE,
ref,
width: 100,
height: 100,
gl: getMockContext(),
onLoad: () => {
if (onLoadCalled) {
return;
}
onLoadCalled = true;

const deck = ref.current?.deck;
t.ok(deck, 'DeckGL is initialized');
const widgets = deck?.props.widgets;
t.is(widgets?.length, 1, 'Only one widget instance remains after StrictMode remount');

act(() => {
root.render(null);
});
container.remove();
t.end();
}
},
createElement(StrictModeWidgetComponent, {id: 'strict-mode-widget'})
)
)
);
});
t.ok(ref.current, 'DeckGL overlay is rendered.');
});
Loading