diff --git a/apis/nucleus/src/components/NebulaApp.jsx b/apis/nucleus/src/components/NebulaApp.jsx index e7fa22b518..1c5927565c 100644 --- a/apis/nucleus/src/components/NebulaApp.jsx +++ b/apis/nucleus/src/components/NebulaApp.jsx @@ -33,7 +33,8 @@ const NebulaApp = forwardRef(({ initialContext, app }, ref) => { } }, setMuiThemeName, - setContext, + setContext: (ctx) => + setContext((oldContext) => (JSON.stringify(oldContext) !== JSON.stringify(ctx) ? ctx : oldContext)), getAppSelections: () => appSelections, })); diff --git a/apis/nucleus/src/components/__tests__/nebulaapp.test.jsx b/apis/nucleus/src/components/__tests__/nebulaapp.test.jsx index 3318fc6fcc..a8491f3f64 100644 --- a/apis/nucleus/src/components/__tests__/nebulaapp.test.jsx +++ b/apis/nucleus/src/components/__tests__/nebulaapp.test.jsx @@ -193,4 +193,56 @@ describe('', () => { act(() => ref.current.removeComponent(MyFoo)); expect(() => renderer.root.findByType(MyFoo)).toThrow(); }); + + test('setContext should trigger a new render of compontnts using it if and only if it has changed', async () => { + let renderCount = 0; + const Foo = () => { + React.useContext(InstanceContext); + ++renderCount; + return 'foo'; + }; + const MyFoo = ; + await render(); + act(() => ref.current.addComponent(MyFoo)); + expect(renderCount).toEqual(1); + + // new context + act(() => + ref.current.setContext({ + keyboardNavigation: true, + constraints: {}, + theme: 'classic', + language: 'pseudo', + deviceType: 'unit-test', + }) + ); + // increased render count + expect(renderCount).toEqual(2); + + // same context + act(() => + ref.current.setContext({ + keyboardNavigation: true, + constraints: {}, + theme: 'classic', + language: 'pseudo', + deviceType: 'unit-test', + }) + ); + // unchanged render count + expect(renderCount).toEqual(2); + + // new context + act(() => + ref.current.setContext({ + keyboardNavigation: true, + constraints: { active: true }, + theme: 'classic', + language: 'pseudo', + deviceType: 'unit-test', + }) + ); + // increased render count + expect(renderCount).toEqual(3); + }); });