-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseDebounceEffect.js
More file actions
41 lines (35 loc) · 1.33 KB
/
useDebounceEffect.js
File metadata and controls
41 lines (35 loc) · 1.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/* This is not code written by me. I found it online. */
import { useEffect, useRef } from "react"
/**
* A debounced useEffect hook that handles async logic and request cancellation.
* @param {Function} effect - Async function receiving (signal) as an argument.
* @param {Array} deps - Dependency array.
* @param {number} delay - Debounce delay in ms.
*/
export function useDebounceEffect(effect, deps, delay = 500) {
const timeoutRef = useRef(null)
const controllerRef = useRef(null)
useEffect(() => {
// cancel previous timeout and abort previous request if dependencies change
if (timeoutRef.current) clearTimeout(timeoutRef.current)
if (controllerRef.current) controllerRef.current.abort()
const controller = new AbortController()
controllerRef.current = controller
timeoutRef.current = setTimeout(() => {
;(async () => {
try {
await effect(controller.signal)
} catch (err) {
if (err.name === "AbortError") return
console.error("useDebounceEffect error:", err)
}
})()
}, delay)
// cleanup on unmount or dependency change
return () => {
if (timeoutRef.current) clearTimeout(timeoutRef.current)
if (controllerRef.current) controllerRef.current.abort()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps)
}