@forge/react

11.17.0-experimental-04cc2b911.18.0-next.0
out/hooks/useTheme.js
~out/hooks/useTheme.jsModified
+42−12
Index: package/out/hooks/useTheme.js
===================================================================
--- package/out/hooks/useTheme.js
+++ package/out/hooks/useTheme.js
@@ -6,32 +6,62 @@
 const bridge_1 = require("@forge/bridge");
 const isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
 const useTheme = () => {
     const [theme, setTheme] = (0, react_1.useState)(null);
+    const themeRef = (0, react_1.useRef)(null);
     const themeLoadedRef = (0, react_1.useRef)(false);
+    const loadingContextRef = (0, react_1.useRef)(false);
+    const applyTheme = (0, react_1.useCallback)((nextTheme) => {
+        if ((0, isEqual_1.default)(themeRef.current, nextTheme)) {
+            return;
+        }
+        themeRef.current = nextTheme;
+        setTheme((current) => ((0, isEqual_1.default)(current, nextTheme) ? current : nextTheme));
+    }, []);
     (0, react_1.useEffect)(() => {
+        let cancelled = false;
         void (async () => {
-            if (!themeLoadedRef.current) {
+            if (themeLoadedRef.current || loadingContextRef.current) {
+                return;
+            }
+            loadingContextRef.current = true;
+            try {
                 const context = await bridge_1.view.getContext();
-                if (context?.theme && !themeLoadedRef.current) {
-                    setTheme((currentTheme) => {
-                        return (0, isEqual_1.default)(currentTheme, context.theme) ? currentTheme : context.theme;
-                    });
-                    themeLoadedRef.current = true;
+                if (cancelled || !context?.theme || themeLoadedRef.current) {
+                    return;
                 }
+                applyTheme(context.theme);
+                themeLoadedRef.current = true;
             }
+            finally {
+                loadingContextRef.current = false;
+            }
         })();
-    }, []);
+        return () => {
+            cancelled = true;
+        };
+    }, [applyTheme]);
     (0, react_1.useEffect)(() => {
+        let unsubscribeFn = null;
+        let cancelled = false;
         const sub = bridge_1.events.on('FORGE_CORE_THEME_CHANGED', ({ theme: updatedTheme }) => {
             themeLoadedRef.current = true;
-            setTheme((currentTheme) => {
-                return (0, isEqual_1.default)(currentTheme, updatedTheme) ? currentTheme : updatedTheme;
-            });
+            applyTheme(updatedTheme);
         });
+        void sub.then((subscription) => {
+            if (cancelled) {
+                subscription.unsubscribe();
+            }
+            else {
+                unsubscribeFn = () => subscription.unsubscribe();
+            }
+        });
         return () => {
-            void sub.then((subscription) => subscription.unsubscribe());
+            cancelled = true;
+            if (unsubscribeFn) {
+                unsubscribeFn();
+            }
         };
-    }, []);
+    }, [applyTheme]);
     return theme;
 };
 exports.useTheme = useTheme;