Description
Several context providers pass fresh object literals as value, causing every consumer to re-render whenever the provider's parent re-renders — even if the actual values haven't changed.
Files to change
1. surfsense_web/components/ui/toggle-group.tsx (line 43)
<ToggleGroupContext.Provider value={{ variant, size, spacing }}>
Fix:
const contextValue = useMemo(() => ({ variant, size, spacing }), [variant, size, spacing]);
<ToggleGroupContext.Provider value={contextValue}>
2. surfsense_web/components/ui/animated-tabs.tsx (line 206)
<TabsContext.Provider value={{ activeValue, onValueChange: handleValueChange }}>
Fix: useMemo(() => ({ activeValue, onValueChange: handleValueChange }), [activeValue, handleValueChange])
3. surfsense_web/contexts/LocaleContext.tsx (line 69)
<LocaleContext.Provider value={{ locale, messages, setLocale }}>
Fix: First, wrap setLocale (line 52) in useCallback since it's recreated every render. Then useMemo the context value:
const setLocale = useCallback((newLocale: Locale) => { ... }, []);
const contextValue = useMemo(() => ({ locale, messages, setLocale }), [locale, messages, setLocale]);
4. surfsense_web/components/editor/plate-editor.tsx (lines 162-168)
<EditorSaveContext.Provider value={{ onSave, hasUnsavedChanges, isSaving, canToggleMode }}>
Fix: useMemo(() => ({ onSave, hasUnsavedChanges, isSaving, canToggleMode }), [onSave, hasUnsavedChanges, isSaving, canToggleMode])
Acceptance criteria
- All listed context providers use
useMemo for their value prop
- Unstable callbacks (like
setLocale) are wrapped in useCallback
- All context consumers still work correctly
Description
Several context providers pass fresh object literals as
value, causing every consumer to re-render whenever the provider's parent re-renders — even if the actual values haven't changed.Files to change
1.
surfsense_web/components/ui/toggle-group.tsx(line 43)Fix:
2.
surfsense_web/components/ui/animated-tabs.tsx(line 206)Fix:
useMemo(() => ({ activeValue, onValueChange: handleValueChange }), [activeValue, handleValueChange])3.
surfsense_web/contexts/LocaleContext.tsx(line 69)Fix: First, wrap
setLocale(line 52) inuseCallbacksince it's recreated every render. ThenuseMemothe context value:4.
surfsense_web/components/editor/plate-editor.tsx(lines 162-168)Fix:
useMemo(() => ({ onSave, hasUnsavedChanges, isSaving, canToggleMode }), [onSave, hasUnsavedChanges, isSaving, canToggleMode])Acceptance criteria
useMemofor theirvaluepropsetLocale) are wrapped inuseCallback