diff --git a/src/hooks/__tests__/useAutoReset.test.ts b/src/hooks/__tests__/useAutoReset.test.ts new file mode 100644 index 00000000..d1095835 --- /dev/null +++ b/src/hooks/__tests__/useAutoReset.test.ts @@ -0,0 +1,21 @@ +import { act, renderHook, waitFor } from '@testing-library/react'; +import useAutoReset from '../useAutoReset'; + +describe('useAutoReset hook', () => { + it('should reset state to initial value after a specified delay', async () => { + const initialValue = false; + const newValue = true; + const { result } = renderHook(() => useAutoReset(initialValue)); + + expect(result.current[0]).toBe(initialValue); + + act(() => result.current[1](newValue)); + + expect(result.current[0]).toBe(newValue); + + await waitFor( + () => expect(result.current[0]).toBe(initialValue), + { timeout: 2000 } + ); + }); +}); diff --git a/src/hooks/useAutoReset.ts b/src/hooks/useAutoReset.ts new file mode 100644 index 00000000..dffa8138 --- /dev/null +++ b/src/hooks/useAutoReset.ts @@ -0,0 +1,29 @@ +import { useEffect, useRef, useState } from 'react'; + +/** + * Custom hook that resets a value to its initial state after a specified delay. + * + * @param initialValue - The initial value. + * @param resetDelayMs - The reset delay in milliseconds. Default is 1000. + * @returns A tuple containing the current value, and a function to set a new value. + */ +function useAutoReset(initialValue: T, resetDelayMs = 1000) { + const [internalValue, setInternalValue] = useState(initialValue); + const timerRef = useRef(null); + + const clearTimer = () => { + if (timerRef.current) clearTimeout(timerRef.current); + }; + + const setValue = (newValue: T) => { + setInternalValue(newValue); + clearTimer(); + timerRef.current = setTimeout(() => setInternalValue(initialValue), resetDelayMs); + }; + + useEffect(() => clearTimer, []); + + return [internalValue, setValue] as const; +} + +export default useAutoReset;