From 02d4e34a3ba2794fb44954631be86d5a07c829d7 Mon Sep 17 00:00:00 2001 From: Johnson Mao Date: Thu, 21 Sep 2023 23:36:45 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20use=20auto=20reset=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useAutoReset.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/hooks/useAutoReset.ts 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; From da5c39036279deb2a6fcb40594ad5250f8c21252 Mon Sep 17 00:00:00 2001 From: Johnson Mao Date: Fri, 22 Sep 2023 17:56:15 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=85=20use=20auto=20reset=20hook=20uni?= =?UTF-8?q?t=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/__tests__/useAutoReset.test.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/hooks/__tests__/useAutoReset.test.ts 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 } + ); + }); +});