From 69de5d3f1d191826b5c00ff6968c12c287c5544c Mon Sep 17 00:00:00 2001 From: Aliullov Vlad Date: Wed, 6 May 2026 18:15:55 +0200 Subject: [PATCH 1/2] =?UTF-8?q?fix=20TypeError=20=E2=80=94=20on=20accessin?= =?UTF-8?q?g=20a=20component=20instance=20while=20unmounting=20(T1327953)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/devextreme-react/src/core/options-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme-react/src/core/options-manager.ts b/packages/devextreme-react/src/core/options-manager.ts index 2681307e8ce4..df00edd60b6b 100644 --- a/packages/devextreme-react/src/core/options-manager.ts +++ b/packages/devextreme-react/src/core/options-manager.ts @@ -167,7 +167,7 @@ class OptionsManager { && e.value instanceof Object && shallowEquals(value as Record, e.value as Record); - if (valuesAreEqual || valuesAreEqualObjects || this.instance.skipOptionsRollBack) { + if (valuesAreEqual || valuesAreEqualObjects || this.instance?.skipOptionsRollBack) { return; } From d1dacc05f07941a1e74a920b5ef93345953a5ede Mon Sep 17 00:00:00 2001 From: Aliullov Vlad Date: Wed, 6 May 2026 18:26:54 +0200 Subject: [PATCH 2/2] add test for T1327953 --- .../core/__tests__/props-updating.test.tsx | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/devextreme-react/src/core/__tests__/props-updating.test.tsx b/packages/devextreme-react/src/core/__tests__/props-updating.test.tsx index e4eca777a6e5..c841f276a9c3 100644 --- a/packages/devextreme-react/src/core/__tests__/props-updating.test.tsx +++ b/packages/devextreme-react/src/core/__tests__/props-updating.test.tsx @@ -1042,6 +1042,38 @@ describe('cfg-component option control', () => { expect((optionsManager as any).setValue).toHaveBeenCalledTimes(1); }); + it('does not crash when option change handler unmounts component (T1327953)', () => { + const optionsManager = new OptionsManagerModule.OptionsManager(); + const config = { + name: '', + predefinedOptions: {}, + initialOptions: {}, + options: { + value: 1, + onValueChange: () => { + optionsManager.dispose(); + }, + }, + templates: [], + configs: {}, + configCollections: {}, + }; + + optionsManager.setInstance({ + skipOptionsRollBack: false, + option: jest.fn(), + resetOption: jest.fn(), + on: jest.fn(), + off: jest.fn(), + beginUpdate: jest.fn(), + endUpdate: jest.fn(), + }, config, ['value'], []); + + expect(() => { + optionsManager.onOptionChanged({ name: 'value', value: 2, fullName: 'value' }); + }).not.toThrow(); + }); + it('apply cfg-component option change if value really change', () => { const TestContainer = (props: any) => { const { value } = props;