Description
Bug Report: Excessive Re-renders in Component Despite Multiple Optimizations
Description
A specific component in our Next.js application exhibits a high number of re-renders (approx. 8-10) even after all asynchronous data fetching (from APIs and Context) is complete and related loading states are false. This occurs despite applying various standard React optimization techniques, including memoizing context providers, functions, and derived state.
Steps to Reproduce
Unfortunately, isolating this issue into a minimal reproducible example has proven difficult due to the component's reliance on multiple contexts and asynchronous operations within our specific application structure. However, the core setup involves:
- A dynamic route page component (e.g.,
/app/items/[itemId]/details/[detailId]
). - The component uses
useEffect
to fetch data from two separate API endpoints based on route parameters (itemId
,detailId
) upon mount and when parameters change. - The component consumes data from two separate contexts (
AuthContext
,FeatureFlagContext
) usinguseContext
. - The component manages multiple states using
useState
for the fetched data, loading status, and error status for both API calls. - Data fetching functions are wrapped in
useCallback
. - Context providers for
AuthContext
andFeatureFlagContext
have theirvalue
prop memoized usinguseMemo
. - Derived state values (e.g.,
isPageLoading
) are memoized usinguseMemo
. - All major functions within the component are memoized using
useCallback
. - An attempt was made to consolidate multiple loading/error states into a single state object, which did not resolve the issue and potentially increased renders.
- React Strict Mode is confirmed to be disabled.
Expected Behavior
After the initial loading phase and subsequent state updates settle (i.e., all loading states are false
, data is populated), the component should render only once or twice more at most, ideally stabilizing without further renders until user interaction or prop changes occur.
Actual Behavior
Console logs show the component rendering approximately 8-10 times after all loading states (bolumLoading
, previewsLoading
, limitLoading
) are false
. This suggests that the sequence or batching of state updates within the asynchronous data fetching functions (fetchItemData
, fetchDetailData
) might be triggering an unexpected cascade of renders, even though the final state values are stable. The number of renders sometimes appeared to increase after applying useCallback
to more functions or attempting state collocation.
Environment
- React:
^18
- Next.js:
^15.3.1
- Node.js: [22.14.0]
- OS: Linux (Pop!_OS 22.04 LTS)
- Browser: [1.77.97 Chromium: 135.0.7049.84 ]
Additional Context
We have applied standard optimization techniques (useMemo
for contexts/derived state, useCallback
for functions) as documented. The persistence of these extra renders after stabilization is unexpected and difficult to debug further without deeper insight into React's internal scheduling or potential interactions between multiple asynchronous state updates within useEffect
.