Skip to content

Commit accb609

Browse files
authored
Merge pull request #33 from gideaoms/gideao/add-guard-for-initial-visibility-check
Fixes #30 - visibility check is only run when visibility child element is active and measurements are calculated
2 parents 7c4ddda + d60a411 commit accb609

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

src/VisibilitySensor.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,11 @@ const VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>(
5858
});
5959
const [lastValue, setLastValue] = useState<boolean | undefined>(undefined);
6060
const [active, setActive] = useState<boolean>(false);
61+
const hasMeasuredRef = useRef(false);
6162

6263
const measureInnerView = () => {
64+
/* Check if the sensor is active to prevent unnecessary measurements
65+
This avoids running measurements when the sensor is disabled or stopped */
6366
if (!active) return;
6467

6568
localRef.current?.measure(
@@ -88,6 +91,9 @@ const VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>(
8891
rectDimensions.rectHeight !== dimensions.rectHeight
8992
) {
9093
setRectDimensions(dimensions);
94+
/* Set hasMeasuredRef to true to indicate that a valid measurement has been taken
95+
This ensures visibility checks only proceed after initial measurement */
96+
hasMeasuredRef.current = true;
9197
}
9298
}
9399
);
@@ -100,7 +106,12 @@ const VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>(
100106
}, [active]);
101107

102108
const stopWatching = useCallback(() => {
103-
if (active) setActive(false);
109+
if (active) {
110+
setActive(false);
111+
/* Reset measurement state when stopping to ensure fresh measurements
112+
when the sensor is reactivated */
113+
hasMeasuredRef.current = false;
114+
}
104115
}, [active]);
105116

106117
useEffect(() => {
@@ -114,6 +125,11 @@ const VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>(
114125
}, [disabled, startWatching, stopWatching]);
115126

116127
useEffect(() => {
128+
/* Ensure visibility checks only run when the sensor is active and
129+
at least one measurement has been completed. This prevents
130+
premature visibility calculations with invalid or stale dimensions */
131+
if (!active || !hasMeasuredRef.current) return;
132+
117133
const window: ScaledSize = Dimensions.get('window');
118134
const isVisible: boolean =
119135
rectDimensions.rectTop + (threshold.top || 0) <= window.height && // Top edge is within the bottom of the window
@@ -129,7 +145,7 @@ const VisibilitySensor = forwardRef<VisibilitySensorRef, VisibilitySensorProps>(
129145
}
130146
}
131147
// eslint-disable-next-line react-hooks/exhaustive-deps
132-
}, [rectDimensions, lastValue]);
148+
}, [rectDimensions, lastValue, active]);
133149

134150
return (
135151
<View ref={localRef} {...rest}>

0 commit comments

Comments
 (0)