Prevent enterAll and leaveAll from calling callbacks on observers with no observed nodes #54
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR addresses an issue encountered in React where callbacks were being invoked on observers that had unobserved all nodes. React frequently registers and unregisters callbacks during its life cycle, which often resulted in observers being left with no observed nodes.
To resolve this, the PR modifies the behaviour of the enterAll and leaveAll functions to skip calling callbacks on observers that have unobserved all nodes. This ensures that observers only receive callbacks when they have actively observed nodes, this prevents the callback functions from being called with an empty array, which should be impossible in non test scenarios.
Example code that would cause the existence of empty observers. If a child component with this kind of useEffect is being added and removed from the dom during a test it would create a series of IntersectionObservers that are not subscribed to a node.
Changes:
It seemed most efficient to update the MockedIntersectionObserver to simply return if triggerNodes was called with an empty array. EnterAll and LeaveAll both call this method with a mapped array of the observers nodes.
Notes:
If for some reason we need to support calling IntersectionObservers that are not currently observing any nodes we could add an argument to enterAll and leaveAll methods to indicate if empty observers should be called. However, I think it makes sense to not call observers that aren't observing anything.