Skip to content

Commit ddbdec4

Browse files
prevent early guard firing (#875)
1 parent 0a9ffe1 commit ddbdec4

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

packages/devextreme-react/src/core/__tests__/props-updating.test.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,22 @@ describe('option control', () => {
298298
});
299299
});
300300

301+
it('rolls back controlled options on second timer (to account for async React 18+ updates)', () => {
302+
render(
303+
<ControlledComponent everyOption={123} />,
304+
);
305+
306+
fireOptionChange('everyOption', 234);
307+
jest.runOnlyPendingTimers();
308+
309+
expect(Widget.option.mock.calls.length).toBe(0);
310+
311+
jest.runAllTimers();
312+
313+
expect(Widget.option.mock.calls.length).toBe(1);
314+
expect(Widget.option.mock.calls[0]).toEqual(['everyOption', 123]);
315+
});
316+
301317
it('rolls back controlled complex option', () => {
302318
render(
303319
<ControlledComponent complexOption={{ a: 123, b: 234 }} />,
@@ -412,6 +428,25 @@ describe('option control', () => {
412428
expect(Widget.option.mock.calls[0]).toEqual(['everyOption', 234]);
413429
});
414430

431+
it('applies option change with async React 18+ update', () => {
432+
const { rerender } = render(
433+
<ControlledComponent everyOption={123} />,
434+
);
435+
436+
fireOptionChange('everyOption', 234);
437+
438+
jest.runOnlyPendingTimers();
439+
expect(Widget.option.mock.calls.length).toBe(0);
440+
441+
rerender(
442+
<ControlledComponent everyOption={234} />,
443+
);
444+
445+
jest.runAllTimers();
446+
expect(Widget.option.mock.calls.length).toBe(1);
447+
expect(Widget.option.mock.calls[0]).toEqual(['everyOption', 234]);
448+
});
449+
415450
it('applies complex option change', () => {
416451
const { rerender } = render(
417452
<ControlledComponent complexOption={{ a: 123 }} />,

packages/devextreme-react/src/core/options-manager.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@ import type { IConfigNode } from './configuration/config-node';
99

1010
const optionsManagers = new Set<OptionsManager>();
1111
let guardTimeoutHandler = -1;
12+
let innerGuardTimeoutHandler = -1;
1213

1314
export function unscheduleGuards(): void {
1415
clearTimeout(guardTimeoutHandler);
16+
clearTimeout(innerGuardTimeoutHandler);
1517
}
1618
export function scheduleGuards(): void {
1719
unscheduleGuards();
1820
guardTimeoutHandler = window.setTimeout(() => {
19-
optionsManagers.forEach((optionManager) => optionManager.execGuards());
21+
innerGuardTimeoutHandler = window.setTimeout(() => {
22+
optionsManagers.forEach((optionManager) => optionManager.execGuards());
23+
});
2024
});
2125
}
2226

0 commit comments

Comments
 (0)