diff --git a/packages/react-native/Libraries/IntersectionObserver/__mocks__/NativeIntersectionObserver.js b/packages/react-native/Libraries/IntersectionObserver/__mocks__/NativeIntersectionObserver.js index e66a5e12159..cb3d7fd9d87 100644 --- a/packages/react-native/Libraries/IntersectionObserver/__mocks__/NativeIntersectionObserver.js +++ b/packages/react-native/Libraries/IntersectionObserver/__mocks__/NativeIntersectionObserver.js @@ -96,6 +96,16 @@ const NativeIntersectionObserverMock = { 'unexpected duplicate call to unobserve', ); observations.splice(observationIndex, 1); + + pendingRecords = pendingRecords.filter( + record => + record.intersectionObserverId !== intersectionObserverId || + record.targetInstanceHandle !== + FabricUIManagerMock.__getInstanceHandleFromNode( + // $FlowExpectedError[incompatible-call] + targetShadowNode, + ), + ); }, connect: (notifyIntersectionObserversCallback: () => void): void => { invariant(callback == null, 'unexpected call to connect'); diff --git a/packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.cpp b/packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.cpp index 2c992c64cb1..a3c9eecf4c0 100644 --- a/packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.cpp @@ -70,31 +70,47 @@ void IntersectionObserverManager::unobserve( const ShadowNode& shadowNode) { SystraceSection s("IntersectionObserverManager::unobserve"); - std::unique_lock lock(observersMutex_); + { + std::unique_lock lock(observersMutex_); - auto surfaceId = shadowNode.getSurfaceId(); + auto surfaceId = shadowNode.getSurfaceId(); - auto observersIt = observersBySurfaceId_.find(surfaceId); - if (observersIt == observersBySurfaceId_.end()) { - return; + auto observersIt = observersBySurfaceId_.find(surfaceId); + if (observersIt == observersBySurfaceId_.end()) { + return; + } + + auto& observers = observersIt->second; + + observers.erase( + std::remove_if( + observers.begin(), + observers.end(), + [intersectionObserverId, &shadowNode](const auto& observer) { + return observer.getIntersectionObserverId() == + intersectionObserverId && + ShadowNode::sameFamily( + observer.getTargetShadowNode(), shadowNode); + }), + observers.end()); + + if (observers.empty()) { + observersBySurfaceId_.erase(surfaceId); + } } - auto& observers = observersIt->second; + { + std::unique_lock lock(pendingEntriesMutex_); - observers.erase( - std::remove_if( - observers.begin(), - observers.end(), - [intersectionObserverId, &shadowNode](const auto& observer) { - return observer.getIntersectionObserverId() == - intersectionObserverId && - ShadowNode::sameFamily( - observer.getTargetShadowNode(), shadowNode); - }), - observers.end()); - - if (observers.empty()) { - observersBySurfaceId_.erase(surfaceId); + pendingEntries_.erase( + std::remove_if( + pendingEntries_.begin(), + pendingEntries_.end(), + [intersectionObserverId, &shadowNode](const auto& entry) { + return entry.intersectionObserverId == intersectionObserverId && + ShadowNode::sameFamily(*entry.shadowNode, shadowNode); + }), + pendingEntries_.end()); } }