Skip to content

Commit 3e5a2cb

Browse files
committed
fix(core): use ref to ensure persistent values across renders
1 parent 47492ba commit 3e5a2cb

File tree

1 file changed

+65
-11
lines changed

1 file changed

+65
-11
lines changed

src/index.ts

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,93 @@
1-
import { useState, useEffect, useCallback } from 'react';
1+
import { useState, useEffect, useCallback, useRef } from 'react';
22

33
/** Enumeration for axis values */
44
export enum Axis {
5+
/**
6+
* The x-axis represents the horizontal direction.
7+
*/
58
X = 'x',
9+
/**
10+
* The y-axis represents the vertical direction.
11+
*/
612
Y = 'y'
713
}
814

915
/** Enumeration for direction values */
1016
export enum Direction {
17+
/**
18+
* The up direction represents the scroll direction moving towards the top.
19+
*/
1120
Up = 'up',
21+
/**
22+
* The down direction represents the scroll direction moving towards the bottom.
23+
*/
1224
Down = 'down',
25+
/**
26+
* The left direction represents the scroll direction moving towards the left.
27+
*/
1328
Left = 'left',
29+
/**
30+
* The right direction represents the scroll direction moving towards the right.
31+
*/
1432
Right = 'right',
33+
/**
34+
* The still direction represents the scroll direction when the user is not scrolling.
35+
*/
1536
Still = 'still'
1637
}
1738

1839
type ScrollPosition = {
40+
/**
41+
* The top position represents the distance from the top edge of the page.
42+
*/
1943
top: number;
44+
/**
45+
* The bottom position represents the distance from the bottom edge of the page.
46+
*/
2047
bottom: number;
48+
/**
49+
* The left position represents the distance from the left edge of the page.
50+
*/
2151
left: number;
52+
/**
53+
* The right position represents the distance from the right edge of the page.
54+
*/
2255
right: number;
2356
};
2457

2558
/** Type declaration for the returned scroll information */
2659
type ScrollInfo = {
60+
/**
61+
* The scrollDir represents the current scroll direction.
62+
*/
2763
scrollDir: Direction;
64+
/**
65+
* The scrollPosition represents the current scroll position.
66+
*/
2867
scrollPosition: ScrollPosition;
2968
};
3069

3170
/** Type declaration for scroll properties */
3271
type ScrollProps = {
72+
/**
73+
* The thr represents the threshold value for scroll detection.
74+
*/
3375
thr?: number;
76+
/**
77+
* The axis represents the scroll axis (x or y).
78+
*/
3479
axis?: Axis;
80+
/**
81+
* The scrollUp represents the scroll direction when moving up.
82+
*/
3583
scrollUp?: Direction;
84+
/**
85+
* The scrollDown represents the scroll direction when moving down.
86+
*/
3687
scrollDown?: Direction;
88+
/**
89+
* The still represents the scroll direction when the user is not scrolling.
90+
*/
3791
still?: Direction;
3892
};
3993

@@ -87,18 +141,18 @@ function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
87141
});
88142

89143
const threshold = Math.max(0, thr);
90-
let ticking = false;
91-
let lastScroll = 0;
144+
const ticking = useRef(false);
145+
const lastScroll = useRef(0);
92146

93147
/** Function to update scroll direction */
94148
const updateScrollDir = useCallback(() => {
95149
const scroll = axis === Axis.Y ? window.scrollY : window.scrollX;
96150

97-
if (Math.abs(scroll - lastScroll) >= threshold) {
98-
setScrollDir(scroll > lastScroll ? scrollDown : scrollUp);
99-
lastScroll = Math.max(0, scroll);
151+
if (Math.abs(scroll - lastScroll.current) >= threshold) {
152+
setScrollDir(scroll > lastScroll.current ? scrollDown : scrollUp);
153+
lastScroll.current = Math.max(0, scroll);
100154
}
101-
ticking = false;
155+
ticking.current = false;
102156
}, [axis, threshold, scrollDown, scrollUp]);
103157

104158
useEffect(() => {
@@ -125,20 +179,20 @@ function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
125179
}, []);
126180

127181
useEffect(() => {
128-
lastScroll = axis === Axis.Y ? window.scrollY : window.scrollX;
182+
lastScroll.current = axis === Axis.Y ? window.scrollY : window.scrollX;
129183

130184
/** Function to handle onScroll event */
131185
const onScroll = () => {
132-
if (!ticking) {
186+
if (!ticking.current) {
133187
window.requestAnimationFrame(updateScrollDir);
134-
ticking = true;
188+
ticking.current = true;
135189
}
136190
};
137191

138192
window.addEventListener('scroll', onScroll);
139193

140194
return () => window.removeEventListener('scroll', onScroll);
141-
}, [updateScrollDir]);
195+
}, [axis, updateScrollDir]);
142196

143197
return { scrollDir, scrollPosition };
144198
}

0 commit comments

Comments
 (0)