Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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