Skip to content

prevent callback skipping with triggerOnce and merged refs - #747

Merged
thebuilder merged 1 commit into
thebuilder:mainfrom
djk01281:fix/triggeronce-merged-refs
Feb 18, 2026
Merged

prevent callback skipping with triggerOnce and merged refs#747
thebuilder merged 1 commit into
thebuilder:mainfrom
djk01281:fix/triggeronce-merged-refs

Conversation

@djk01281

@djk01281djk01281 commented Feb 3, 2026

Copy link
Copy Markdown
Contributor

Hello! 👋🏻 I ran into this bug while using multiple useInView hooks with merged refs, so I opened an issue and put together this fix.

Let me know if anything needs to be changed!

Loving the library by the way : )

Description

Fixes#746

This PR fixes a bug where callbacks are skipped when multiple useInView({ triggerOnce: true }) hooks are merged on the same element.

Problem

When a callback executes with triggerOnce: true, it calls unobserve() which removes the callback from the array using splice(). This modifies the array during forEach iteration, causing subsequent callbacks to be skipped.

Solution

Copy the callbacks array before iterating using the spread operator:

[...elements.get(entry.target)??[]].forEach((callback)=>{callback(inView,entry);});

This prevents the iteration from being affected by array modifications.

Changes

  • src/observe.ts: Use spread operator to copy callbacks array before iteration
  • src/tests/useInView.test.tsx: Add test case to verify all callbacks are triggered with triggerOnce and merged refs

Testing

Added a new test that reproduces the bug:

  • Creates 3 useInView hooks with triggerOnce: true
  • Merges all refs onto a single element
  • Verifies all 3 hooks receive inView: true
image

Before fix: Test fails - only hooks 1 and 3 trigger, hook 2 remains false


image

After fix: Test passes - all 3 hooks trigger correctly : )

@bolt-new-by-stackblitz

Copy link
Copy Markdown

Review PR in StackBlitz CodeflowRun & review this pull request in StackBlitz Codeflow.

@vercel

vercelBot commented Feb 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
react-intersection-observerReadyReadyPreview, CommentFeb 3, 2026 1:36pm

@pkg-pr-new

pkg-pr-newBot commented Feb 6, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/thebuilder/react-intersection-observer@747

commit: 50f709d

@thebuilder

Copy link
Copy Markdown
Owner

Looks good, thanks for fixing it. On vacation, but will release it in a couple of weeks.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a regression/edge-case in the IntersectionObserver callback dispatch where multiple useInView({ triggerOnce: true }) listeners attached to the same element (via merged refs) could be skipped due to in-loop mutation of the callbacks array.

Changes:

  • Prevent callback skipping by iterating over a copied callbacks array in the observer entry handler.
  • Add a regression test covering multiple triggerOnce hooks merged onto a single element.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

FileDescription
src/observe.tsIterates over a snapshot of the callbacks list to avoid splice() mutation during iteration.
src/__tests__/useInView.test.tsxAdds a test reproducing and validating the fix for merged refs + triggerOnce.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@thebuilder
thebuilder merged commit cfb2fc6 into thebuilder:mainFeb 18, 2026
15 checks passed
Sign up for freeto 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: Callbacks skipped when using triggerOnce with merged refs

3 participants

@djk01281@thebuilder