Skip to content

PWA Phase 3: Fix infinite loop risk in NotificationPreferences with Lingui translations #103

@kevalyq

Description

@kevalyq

🐛 Bug Description

Component: src/components/NotificationPreferences.tsx (lines 76-91)
Severity: MEDIUM
Origin: Copilot review comment in PR #100

Problem

The NotificationPreferences component has a potential infinite loop risk due to how translations are handled:

const defaultPreferences = useMemo<NotificationPreference[]>(
  () => [...],
  [_]  // ← Depends on _ function
);

useEffect(() => {
  setPreferences((current) =>
    current.map((pref) => {
      const defaultPref = defaultPreferences.find(...);
      return defaultPref ? { ...pref, label: defaultPref.label, ... } : pref;
    })
  );
}, [defaultPreferences]);  // ← Triggers on _ function changes

Issue: The Lingui _ function reference may change frequently during re-renders, causing defaultPreferences to be recomputed, which then triggers the useEffect, which updates state, causing re-render... → potential infinite loop.

Expected Behavior

Translations should only update when the locale actually changes, not on every _ function reference change.

Proposed Solution

Depend on locale instead of defaultPreferences:

const locale = useLingui().i18n.locale;

useEffect(() => {
  // Only update when locale changes, not on every _ function reference change
  setPreferences((current) =>
    current.map((pref) => {
      const defaultPref = defaultPreferences.find(
        (d) => d.category === pref.category
      );
      return defaultPref
        ? { ...pref, label: defaultPref.label, description: defaultPref.description }
        : pref;
    })
  );
}, [locale]); // ← Depend on locale instead

Reproduction Steps

  1. Open NotificationPreferences component
  2. Change language rapidly (if multi-language switching is available)
  3. Monitor for excessive re-renders

Context

Acceptance Criteria

  • useEffect depends on locale instead of defaultPreferences
  • Translations still update correctly when language changes
  • No excessive re-renders detected
  • Tests updated to verify translation updates work correctly

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions