1
- import { useState , useEffect } from "react" ;
1
+ import { useState , useEffect , useCallback , useRef } from "react" ;
2
+ import { throttle } from "lodash" ;
2
3
3
4
/**
4
5
* Hook to detect if the viewport is in mobile size
5
6
* @param breakpoint - The breakpoint in pixels (default: 768)
7
+ * @param throttleMs - The throttle delay in milliseconds (default: 100)
6
8
* @returns boolean indicating if viewport is mobile size
7
9
*/
8
- export function useIsMobile ( breakpoint : number = 768 ) : boolean {
10
+ export function useIsMobile ( breakpoint : number = 768 , throttleMs : number = 100 ) : boolean {
9
11
const [ isMobile , setIsMobile ] = useState ( ( ) => {
10
12
// Initial state based on current window width
11
13
if ( typeof window !== "undefined" ) {
@@ -14,17 +16,23 @@ export function useIsMobile(breakpoint: number = 768): boolean {
14
16
return false ;
15
17
} ) ;
16
18
17
- useEffect ( ( ) => {
18
- const checkMobile = ( ) => {
19
- setIsMobile ( window . innerWidth < breakpoint ) ;
20
- } ;
19
+ const throttledCheckMobile = useRef < ( ( ) => void ) | null > ( null ) ;
21
20
22
- checkMobile ( ) ;
21
+ const checkMobile = useCallback ( ( ) => {
22
+ setIsMobile ( window . innerWidth < breakpoint ) ;
23
+ } , [ breakpoint ] ) ;
23
24
24
- window . addEventListener ( "resize" , checkMobile ) ;
25
+ useEffect ( ( ) => {
26
+ throttledCheckMobile . current = throttle ( checkMobile , throttleMs ) ;
27
+ checkMobile ( ) ;
28
+ window . addEventListener ( "resize" , throttledCheckMobile . current ) ;
25
29
26
- return ( ) => window . removeEventListener ( "resize" , checkMobile ) ;
27
- } , [ breakpoint ] ) ;
30
+ return ( ) => {
31
+ if ( throttledCheckMobile . current ) {
32
+ window . removeEventListener ( "resize" , throttledCheckMobile . current ) ;
33
+ }
34
+ } ;
35
+ } , [ checkMobile , throttleMs ] ) ;
28
36
29
37
return isMobile ;
30
38
}
0 commit comments