Skip to content

Conversation

@DeJeune
Copy link
Collaborator

@DeJeune DeJeune commented Jan 21, 2026

What this PR does

Before this PR:

  • Components using useProvider, useAllProviders, useSystemProviders, useUserProviders would receive new object references on every render due to normalizeProvider() creating new objects inside useAppSelector callbacks
  • This caused infinite re-render loops ("Maximum update depth exceeded") in components that depend on provider objects in their useEffect dependencies
image

After this PR:

  • Provider selectors are properly memoized using createSelector from Redux Toolkit
  • Components receive stable object references when the underlying data hasn't changed
  • No more infinite re-render loops
image

Fixes the regression introduced in 8186d4f

Why we need it and why it was done in this way

The following tradeoffs were made:

  • Used createSelector for memoization instead of useMemo inside each hook, which is more efficient and follows Redux best practices

The following alternatives were considered:

  • Using useMemo inside each hook - rejected because createSelector provides better memoization at the selector level
  • Removing the normalizeProvider call entirely - rejected because trailing slash normalization is still needed

Breaking changes

None. This is a bug fix that restores the expected behavior.

Special notes for your reviewer

The key insight is that .map(normalizeProvider) inside useAppSelector creates new object references on every render. Moving this into createSelector ensures the result is memoized and only recalculated when the input providers array changes.

Checklist

  • PR: The PR description is expressive enough and will help future contributors
  • Code: Write code that humans can understand and Keep it simple
  • Refactor: You have left the code cleaner than you found it (Boy Scout Rule)
  • Upgrade: Impact of this change on upgrade flows was considered and addressed if required
  • Documentation: Not required for this bug fix

Release note

fix: resolve infinite re-render loop in provider settings and painting pages

🤖 Generated with Claude Code

The normalizeProvider() calls inside useAppSelector callbacks were
creating new object references on every render, causing infinite
re-render loops in components that depend on provider objects.

This fix uses createSelector from Redux Toolkit to properly memoize
the normalized providers, preventing unnecessary re-renders in:
- GithubCopilotSettings (useEffect depends on provider)
- Painting pages (useAllProviders returns new array each render)

Fixes the "Maximum update depth exceeded" error introduced in 8186d4f.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@DeJeune DeJeune force-pushed the fix/maxmium-update branch from 6988dae to 0b39eb0 Compare January 22, 2026 04:40
@DeJeune DeJeune requested a review from kangfenmao January 22, 2026 04:45
@kangfenmao kangfenmao merged commit 1f209dc into main Jan 22, 2026
1 check passed
@kangfenmao kangfenmao deleted the fix/maxmium-update branch January 22, 2026 06:27
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.

3 participants