ソースを参照

[frontend] Adjust the useHuePubSub hook to not update the state when a callback is given

Johan Åhlén 1 年間 前
コミット
0269dd9617

+ 17 - 1
desktop/core/src/desktop/js/reactComponents/useHuePubSub.test.tsx

@@ -1,10 +1,11 @@
 import { renderHook, act } from '@testing-library/react';
 import { useHuePubSub } from './useHuePubSub';
 import huePubSub from '../utils/huePubSub';
+import noop from '../utils/timing/noop';
 
 describe('useHuePubSub', () => {
   const originalSubscribe = huePubSub.subscribe;
-  let publishCallback;
+  let publishCallback: (a: string) => void;
   const remove = jest.fn();
 
   const subscribeMock = jest.fn().mockImplementation((topic, callback) => {
@@ -70,4 +71,19 @@ describe('useHuePubSub', () => {
 
     expect(callbackCalled).toBeTruthy();
   });
+
+  test("when callback is provided there won't be a state update", () => {
+    const { result } = renderHook(() =>
+      useHuePubSub<string>({
+        topic: 'my.test.topic',
+        callback: noop
+      })
+    );
+
+    act(() => {
+      publishCallback('some info');
+    });
+
+    expect(result.current).not.toEqual('some info');
+  });
 });

+ 9 - 5
desktop/core/src/desktop/js/reactComponents/useHuePubSub.ts

@@ -19,9 +19,12 @@ import huePubSub from '../utils/huePubSub';
 
 // Basic helper hook to let a component subscribe to a huePubSub topic and rerender for each message
 // by placing the message/info in a state that is automatically updated.
-// Use with caution and preferrably only at the top level component in your component tree since
+
+// Use with caution and preferably only at the top level component in your component tree since
 // we don't want to have states stored all over the app.
 
+// When a callback is provided the state will not be updated.
+
 export function useHuePubSub<T>({
   topic,
   callback,
@@ -41,11 +44,12 @@ export function useHuePubSub<T>({
       info => {
         if (callback) {
           callback(info);
+        } else {
+          // Always create a new state so that the React component is re-rendered even
+          // if the info is the same as previous info. This is to stay aligned with the idea
+          // of having a component being notified for EVERY message for the topics it subscribes to.
+          setHuePubSubState(() => ({ info }));
         }
-        // Always create a new state so that the react component is rerendered even
-        // if the info is the same as previous info. This is to stay aligned with the idea
-        // of having a component being notified for EVERY message for the topics it subscribes to.
-        setHuePubSubState(() => ({ info }));
       },
       app
     );