Skip to content

fix(626): stabilize SettingRow onPress/right/icon props to prevent un… - #886

Merged
RUKAYAT-CODER merged 1 commit into
rinafcode:mainfrom
Muyideen-js:fix/626-settingrow-callback-stability
Jul 27, 2026
Merged

fix(626): stabilize SettingRow onPress/right/icon props to prevent un…#886
RUKAYAT-CODER merged 1 commit into
rinafcode:mainfrom
Muyideen-js:fix/626-settingrow-callback-stability

Conversation

@Muyideen-js

Copy link
Copy Markdown
Contributor

Fix: SettingRow onPress/right/icon props recreated on every parent render — breaks React.memo optimization

Closes #626

Problem

SettingRow (in MobileSettings.tsx and NotificationSettings.tsx) is wrapped with React.memo, but every parent re-render (theme toggle, store state change) created new function/JSX references for all props:

  1. icon prop — Inline JSX (<Eye size={18} color="#6366f1" />) created a new object every render → defeats React.memo
  2. right prop — Inline SettingsPicker / NativeToggle JSX also created new references
  3. onPress prop — Several callbacks from parent props (onChangePassword, onLinkedAccounts) were not wrapped in useCallback
  4. onValueChange — Inline arrow functions in NotificationSettings broke memo on SettingRow

This caused every SettingRow in the settings list to re-render on any unrelated store change (theme, user, network), wasting CPU cycles.

Changes

src/components/mobile/MobileSettings.tsx

Change Detail
Static icon constants Extracted 18 static icon JSX elements to module-level constants (ICON_EYE, ICON_LOCK, etc.) — created once, never change
useMemo for right elements Memoized all SettingsPicker / NativeToggle instances with correct dependency arrays (profileVisibilityRight, twoFactorRight, etc.)
handleChangePassword New useCallback wrapping parent onChangePassword prop
handleLinkedAccounts New useCallback wrapping parent onLinkedAccounts prop

app/settings.tsx

Change Detail
handleSignOut Wrapped with useCallback with [logout, router] deps — stabilizes the onSignOut prop passed to MobileSettings

src/components/mobile/NotificationSettings.tsx

Change Detail
handlePreferenceChange Wrapped with useCallback with [setPreference] dep
handleToggleAdvancedNotifications Wrapped with useCallback with [] dep
5 stable onValueChange handlers handleCourseUpdatesChange, handleMessagesChange, handleLearningRemindersChange, handleAchievementUnlocksChange, handleCommunityActivityChange — each wrapped in useCallback delegating to handlePreferenceChange

Verification

  • SettingRow has React.memo in both MobileSettings.tsx and NotificationSettings.tsx
  • ✅ All useCallback / useMemo dependency arrays are correct (no missing deps)
  • ✅ No TypeScript errors in changed files
  • ✅ Profiler should confirm 0 re-renders for settings rows on unrelated store changes (e.g., theme toggle)

Testing

  1. TypeScript: npx tsc --noEmit — only pre-existing errors in unrelated files
  2. React Profiler: Navigate to Settings, toggle theme — SettingRow instances should not re-render

Impact

  • Performance: Eliminates O(n) unnecessary re-renders for every SettingRow on each parent update
  • Files changed: 3
  • Net change: +196 / −93 lines

…necessary re-renders

- Extract static icon JSX to module-level constants for stable references across renders

- Memoize dynamic right elements (SettingsPicker, NativeToggle) with useMemo

- Wrap onChangePassword/onLinkedAccounts parent props with useCallback in MobileSettings

- Wrap handleSignOut with useCallback in app/settings.tsx

- Wrap inline onValueChange arrow functions with useCallback in NotificationSettings

- All useCallback/useMemo dependency arrays are correct and complete
@drips-wave

drips-wave Bot commented Jul 27, 2026

Copy link
Copy Markdown

@Muyideen-js Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Thank you for contributing to the project.

@RUKAYAT-CODER
RUKAYAT-CODER merged commit 9fe86ad into rinafcode:main Jul 27, 2026
1 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] SettingRow right prop callback recreated on every parent render — breaks PureComponent optimization

2 participants