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);
+ });
});