From 958665b81c826a52e64a34c0ff4d834ee9e63704 Mon Sep 17 00:00:00 2001 From: Lukas Weiss Date: Wed, 7 Feb 2024 15:50:07 +0100 Subject: [PATCH] improve use-filter hook to only run on change (and not on first render anymore) --- src/components/filter/useFilter.ts | 37 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/components/filter/useFilter.ts b/src/components/filter/useFilter.ts index 2abca890..016403a9 100644 --- a/src/components/filter/useFilter.ts +++ b/src/components/filter/useFilter.ts @@ -1,6 +1,5 @@ -import { useDebounce } from '@aboutbits/react-toolbox' import { - ChangeEventHandler, + ChangeEvent, useCallback, useEffect, useMemo, @@ -39,19 +38,7 @@ export function useFilter() { }, []) const settingNewValueRef = useRef(false) - - const [internalValue, setInternalValue] = useState(value) - const debouncedInternalValue = useDebounce(internalValue, debounceInterval) - const oldDebouncedInternalValueRef = useRef() - - useEffect(() => { - // Check that the debounced value is new, because `setValue` might not be reference stable and trigger this effect even though the debounced value did not change - if (debouncedInternalValue !== oldDebouncedInternalValueRef.current) { - oldDebouncedInternalValueRef.current = debouncedInternalValue - setValue(debouncedInternalValue) - settingNewValueRef.current = false - } - }, [debouncedInternalValue, setValue]) + const timeoutRef = useRef(null) useEffect(() => { if (element && !settingNewValueRef.current) { @@ -59,10 +46,22 @@ export function useFilter() { } }, [value, element]) - const onChange: ChangeEventHandler = (e) => { - settingNewValueRef.current = true - setInternalValue(e.target.value as TValue) - } + const onChange = useCallback( + (e: ChangeEvent) => { + settingNewValueRef.current = true + + if (timeoutRef.current) { + clearTimeout(timeoutRef.current) + timeoutRef.current = null + } + + timeoutRef.current = setTimeout(() => { + setValue(e.target.value as TValue) + settingNewValueRef.current = false + }, debounceInterval) + }, + [debounceInterval, setValue], + ) return { ref: elementRef,