Skip to content

Commit

Permalink
fix: Properly handle effect mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
roderickhsiao committed Sep 20, 2024
1 parent 7ba72f9 commit 486f321
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 41 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-in-viewport",
"version": "1.0.0-beta.3",
"version": "1.0.0-beta.4",
"description": "Track React component in viewport using Intersection Observer API",
"author": "Roderick Hsiao <[email protected]>",
"license": "MIT",
Expand Down
72 changes: 32 additions & 40 deletions src/lib/useInViewport.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, {
useCallback,
useEffect,
useRef,
useState,
Expand All @@ -9,32 +8,10 @@ import { defaultOptions, defaultConfig, defaultProps } from './constants';

import type { Config, CallbackProps, Options } from './types';

const useDOMObserver = (
ref: React.RefObject<HTMLElement>,
onChange: (mutations: MutationRecord[]) => void,
options: MutationObserverInit = {
attributes: true,
childList: true,
subtree: true,
},
) => {
useEffect(() => {
const currentElement = ref.current;
let observer: MutationObserver;
if (currentElement) {
observer = new MutationObserver(onChange);

// Start observing the DOM element for mutations
observer.observe(currentElement, options);
}

// Cleanup function to stop observing when the component unmounts
return () => {
if (observer) {
observer.disconnect();
}
};
}, [ref, onChange, options]);
const defaultMutationObserverOption = {
attributes: true,
childList: true,
subtree: true,
};

const useInViewport = (
Expand Down Expand Up @@ -116,7 +93,11 @@ const useInViewport = (
return observerRef;
}

const attachObserver = useCallback(({ observerRef }) => {
useEffect(() => {
let observerRef = observer.current;
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
observerRef = initIntersectionObserver({ observerRef });

startObserver({
observerRef,
});
Expand All @@ -126,23 +107,34 @@ const useInViewport = (
observerRef,
});
};
}, []);
}, [target.current, options, config, onEnterViewport, onLeaveViewport]);

const handleMutation = useCallback(() => {
// handles when ref changes
useEffect(() => {
const currentElement = target.current;
const observerRef = observer.current;
attachObserver({ observerRef });
}, []);

useEffect(() => {
let observerRef = observer.current;
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
observerRef = initIntersectionObserver({ observerRef });
const handleOnChange = () => {
startObserver({
observerRef,
});
};

let mutationObserver: MutationObserver;
if (currentElement) {
mutationObserver = new MutationObserver(handleOnChange);

attachObserver({ observerRef });
}, [options, config, onEnterViewport, onLeaveViewport]);
// Start observing the DOM element for mutations
mutationObserver.observe(currentElement, defaultMutationObserverOption);
}

// handles when ref changes
useDOMObserver(target, handleMutation);
// Cleanup function to stop observing when the component unmounts
return () => {
if (observer) {
mutationObserver.disconnect();
}
};
}, [target.current]);

return {
inViewport: inViewportRef.current,
Expand Down

0 comments on commit 486f321

Please sign in to comment.