From 3ce453675cb12ab5c82b51303f203c7e491607b1 Mon Sep 17 00:00:00 2001 From: Michael Bashurov Date: Tue, 3 Nov 2020 14:15:13 +0200 Subject: [PATCH] fix(observer): fix of reobserve doesn't add observer to map When new element already holds a ref to an observer and the previous element (that used the same observer) unobserves, it creates a broken state when that observer is deleted from map, but new element holds that ref and thinks it's ok to observe Essentially i'm bringing back part of the code deleted in #153, namely https://github.com/researchgate/react-intersection-observer/pull/153/files#diff-44cb04e2627c3ab84281b41d14880e5e822437f19144e8c14a6c95f7f7fa14bbL72 I also added tests to not to break this and #153 in the future --- src/observer.ts | 3 +++ test/unit/observer.spec.js | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/observer.ts b/src/observer.ts index f926e742..b2fa63c7 100644 --- a/src/observer.ts +++ b/src/observer.ts @@ -78,6 +78,9 @@ export function createObserver( } export function observeElement(element: Instance) { + if (element.observer && !observerElementsMap.has(element.observer)) { + observerElementsMap.set(element.observer, new Set()); + } observerElementsMap.get(element.observer)?.add(element); element.observer!.observe(element.target!); } diff --git a/test/unit/observer.spec.js b/test/unit/observer.spec.js index 5b8d33cc..0c527bc2 100644 --- a/test/unit/observer.spec.js +++ b/test/unit/observer.spec.js @@ -194,4 +194,20 @@ describe('findObserverElement', () => { expect(instance1).toEqual(entry1); expect(instance2).toEqual(entry2); }); + + test('two subsequent createObserver calls should not produce two observers', () => { + const observer1 = createObserver(); + const observer2 = createObserver(); + expect(observer1).toEqual(observer2); + }); + + test('observing element should add target to observerElementsMap even if there is no such observer key', () => { + const observer = createObserver(); + const entry = { observer, target: target1 }; + observeElement(entry); + unobserveElement(entry, entry.target); + observeElement(entry); + const instance = findObserverElement(observer, entry); + expect(instance).toEqual(entry); + }); });