From 8cf957b301091ea44d41ba7bda319e09ff765c00 Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Mon, 20 Apr 2026 01:58:20 -0700 Subject: [PATCH] fix(theme-toggle): use functional setIsDark in toggleTheme (#1247) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #1247. toggleTheme's previous implementation read isDark from the closure via setIsDark(!isDark), which forced isDark into the useCallback dependency array. As a result toggleTheme's reference changed on every click, invalidating any downstream memoization. Switched to the functional updater setIsDark((prev) => !prev) and dropped isDark from the dependency list. The sibling setCrazyLightTheme and setCrazyDarkTheme callbacks already use this pattern (they pass concrete values to setIsDark without listing isDark in deps), so this keeps the three theme callbacks consistent. No observable behavior change — clicking the theme toggle still flips isDark. The callback reference is now stable between clicks, which is also safer under concurrent updates per React's standard guidance. --- surfsense_web/components/theme/theme-toggle.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/surfsense_web/components/theme/theme-toggle.tsx b/surfsense_web/components/theme/theme-toggle.tsx index a59c5248b..0b480a1ca 100644 --- a/surfsense_web/components/theme/theme-toggle.tsx +++ b/surfsense_web/components/theme/theme-toggle.tsx @@ -586,7 +586,7 @@ export const useThemeToggle = ({ }, []); const toggleTheme = useCallback(() => { - setIsDark(!isDark); + setIsDark((prev) => !prev); const animation = createAnimation(variant, start, blur, gifUrl); @@ -604,7 +604,7 @@ export const useThemeToggle = ({ } document.startViewTransition(switchTheme); - }, [theme, setTheme, variant, start, blur, gifUrl, updateStyles, isDark]); + }, [theme, setTheme, variant, start, blur, gifUrl, updateStyles]); const setCrazyLightTheme = useCallback(() => { setIsDark(false);