Skip to content

fix(scroll): guard against zero window size in bound detection#2146

Merged
naqvitalha merged 1 commit intomainfrom
fix/1956-guard-zero-window-size
Mar 23, 2026
Merged

fix(scroll): guard against zero window size in bound detection#2146
naqvitalha merged 1 commit intomainfrom
fix/1956-guard-zero-window-size

Conversation

@naqvitalha
Copy link
Collaborator

@naqvitalha naqvitalha commented Mar 11, 2026

Summary

  • Adds a visibleLength <= 0 early return in useBoundDetection to skip onEndReached/onStartReached when the list has no measurable size
  • Prevents infinite loading when the list is mounted off-screen (e.g., background tab) where all measurements are 0

Fixes #1956

Test plan

  • Verify onEndReached no longer fires when list is mounted in a background/hidden tab
  • Verify onEndReached still fires correctly during normal scrolling
  • Unit tests pass (yarn test)

@naqvitalha
Copy link
Collaborator Author

@agent review this PR

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

Claude finished @naqvitalha's task in 1m 49s —— View job


Review of PR #2146


Summary

This PR adds an early return in useBoundDetection when visibleLength <= 0, preventing onEndReached/onStartReached from firing when the list has no measurable size. This fixes #1956 where a FlashList mounted in a background tab (e.g., via deep link into a BottomTabNavigator) would trigger infinite loading because all measurements were 0.

Verdict: Looks good ✅

The fix is minimal, well-placed, and correctly addresses the root cause. A few observations:

What's correct:

  • The guard is placed after getIsFirstLayoutComplete() and after dimensions are read, but before any threshold calculations — exactly the right spot.
  • visibleLength <= 0 correctly handles both zero and any hypothetical negative edge case.
  • The early return skips onEndReached, onStartReached, and the autoscroll-to-bottom logic, all of which depend on meaningful dimensions. This is the right behavior — autoscrolling with zero dimensions is equally nonsensical.
  • The comment clearly explains why this guard exists, which is important for future maintainers.

Minor observations (non-blocking):

  1. pendingEndReached/pendingStartReached refs are not reset on early return — this is actually fine because they default to false and would only be true if a previous call with valid dimensions set them. When the list transitions from hidden to visible, valid measurements will flow in and the threshold logic will re-evaluate naturally. If the list was never visible (the bug scenario), these refs stay false, so the first valid check after becoming visible will correctly trigger onEndReached if near the end.

  2. No unit tests for this hook — there don't appear to be existing tests for useBoundDetection. Given that this is a targeted guard with clear semantics, the manual test plan in the PR description is reasonable. That said, a unit test mocking recyclerViewManager.getWindowSize() to return {width: 0, height: 0} would be a nice addition for regression safety in a follow-up.

Overall: Clean, surgical fix that matches the issue's root cause. The zero-size guard is a sensible invariant to enforce regardless of the specific bug report — there's no valid scenario where bound detection should run against a zero-size window.

@naqvitalha naqvitalha merged commit 2b8ec28 into main Mar 23, 2026
21 of 22 checks passed
@naqvitalha naqvitalha deleted the fix/1956-guard-zero-window-size branch March 23, 2026 18:10
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.

[Android] Infinite list infinitely loading in the background after cold start

2 participants