UNPKG

@supunlakmal/hooks

Version:

A collection of reusable React hooks

337 lines (285 loc) โ€ข 24.9 kB
# @supunlakmal/hooks [![NPM Version](https://img.shields.io/npm/v/@supunlakmal/hooks.svg)](https://www.npmjs.com/package/@supunlakmal/hooks) [![License: ISC](https://img.shields.io/npm/l/@supunlakmal/hooks.svg)](https://opensource.org/licenses/ISC) [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/) ![npm](https://img.shields.io/npm/dt/@supunlakmal/hooks?label=Total%20Downloads&color=brightgreen) [![GitHub last commit](https://img.shields.io/github/last-commit/supunlakmal/hooks)](https://github.com/supunlakmal/hooks/commits/main) [![bundle size](https://img.shields.io/bundlephobia/minzip/@supunlakmal/hooks)](https://bundlephobia.com/package/@supunlakmal/hooks) [![Install Size](https://packagephobia.com/badge?p=@supunlakmal/hooks)](https://packagephobia.com/result?p=@supunlakmal/hooks) <!-- Add other badges as applicable: Downloads, Build Status, Coverage --> **A comprehensive collection of production-ready, reusable React hooks written in TypeScript to simplify common UI patterns and browser API interactions.** Stop reinventing the wheel! `@supunlakmal/hooks` provides a wide arrays, easy-to-use hooks covering everything from state management enhancements and side effects to browser APIs and performance optimizations. **Why choose `@supunlakmal/hooks`?** - **๐Ÿš€ Extensive Collection:** Over 60+ hooks covering a vast range of common React development needs. - **๐Ÿ›ก๏ธ Type-Safe:** Written entirely in TypeScript for robust development. - **โœจ Simple API:** Designed for ease of use and minimal boilerplate. - **๐ŸŒ SSR Compatible:** Hooks are designed to work safely in server-side rendering environments. - **๐Ÿงน Automatic Cleanup:** Handles listeners, timers, and observers correctly. - **โšก Performance Focused:** Includes hooks like `useDebounce`, `useThrottle`, and `useVirtualList` for optimization. - **๐Ÿงฉ Minimal Dependencies:** Core hooks have zero runtime dependencies (unless specified in individual hook docs). ## Installation ```bash npm install @supunlakmal/hooks # or yarn add @supunlakmal/hooks ``` ## Quick Start Example ```jsx import React, { useState } from 'react'; import { useToggle, useDebounce, useWindowSize } from '@supunlakmal/hooks'; function ExampleComponent() { // Effortlessly manage boolean state const [isOpen, toggle] = useToggle(false); // Debounce rapid input changes const [inputValue, setInputValue] = useState(''); const debouncedSearchTerm = useDebounce(inputValue, 500); // Get window dimensions easily const { width, height } = useWindowSize(); // Use debounced value for API calls, etc. React.useEffect(() => { if (debouncedSearchTerm) { console.log(`Searching for: ${debouncedSearchTerm}`); // Fetch API call here... } }, [debouncedSearchTerm]); return ( <div> {/* useToggle Example */} <button onClick={toggle}>{isOpen ? 'Close' : 'Open'}</button> {isOpen && <p>Content is visible!</p>} <hr /> {/* useDebounce Example */} <input type="text" placeholder="Search..." value={inputValue} onChange={(e) => setInputValue(e.target.value)} /> <p>Typing: {inputValue}</p> <p>Debounced: {debouncedSearchTerm}</p> <hr /> {/* useWindowSize Example */} <p> Window Size: {width}px x {height}px </p> </div> ); } ``` ## Available Hooks Hooks are organized into thematic categories so you can quickly jump to the patterns you need. Every entry links to its detailed guide in `docs/`. ### 1. State Management Enhanced `useState`-style primitives for toggles, lists, finite state machines, and other complex data structures. | Hook | Description | | :--- | :--- | | [`useBoolean`](./docs/useBoolean.md) | Manages a boolean state with explicit `setTrue`, `setFalse`, and `toggle` functions. | | [`useConst`](./docs/useConst.md) | Initializes and returns a constant value that persists across renders. | | [`useControlledRerenderState`](./docs/useControlledRerenderState.md) | A `useState` alternative where the state setter can cancel a re-render. | | [`useCounter`](./docs/useCounter.md) | Manages a number state with `increment`, `decrement`, `set`, and `reset` actions. | | [`useCycle`](./docs/useCycle.md) | Cycles through a predefined list of values. | | [`useDefault`](./docs/useDefault.md) | Returns a default value if the provided value is `null` or `undefined`. | | [`useDerivedState`](./docs/useDerivedState.md) | A semantic wrapper around `useMemo` for creating state based on other values. | | [`useEnum`](./docs/useEnum.md) | Manages state that is constrained to the values of a given enum object. | | [`useFiniteStateMachine`](./docs/useFiniteStateMachine.md) | Manages complex state using an explicit finite state machine definition. | | [`useFirstMountState`](./docs/useFirstMountState.md) | Returns `true` only on the first render of a component. | | [`useFunctionalState`](./docs/useFunctionalState.md) | A `useState` variant that returns a getter function for the state. | | [`useHistoryState`](./docs/useHistoryState.md) | Manages state with a history, allowing for undo and redo operations. | | [`useIsFirstRender`](./docs/useIsFirstRender.md) | Returns `true` only on the initial render of a component. | | [`useIsMounted`](./docs/useIsMounted.md) | Returns a function that indicates if the component is currently mounted. | | [`useList`](./docs/useList.md) | Manages an array state with a comprehensive set of list manipulation actions. | | [`useListState`](./docs/useListState.md) | Manages an array state with basic list manipulation functions. | | [`useMap`](./docs/useMap.md) | Manages a `Map` object as state with actions to manipulate it. | | [`useMapState`](./docs/useMapState.md) | Manages a key-value object as state with `set`, `remove`, and `reset` functions. | | [`useMediatedState`](./docs/useMediatedState.md) | A `useState` variant where every value set is passed through a mediator function. | | [`usePrevious`](./docs/usePrevious.md) | Returns the value of a prop or state from the previous render. | | [`usePreviousDifferent`](./docs/usePreviousDifferent.md) | Returns the last value that was different from the current value. | | [`useQueue`](./docs/useQueue.md) | Manages a queue (First-In, First-Out) with methods to `add`, `remove`, and `peek`. | | [`useResetState`](./docs/useResetState.md) | A `useState` variant that includes a function to reset the state to its initial value. | | [`useSet`](./docs/useSet.md) | Manages a `Set` object as state with actions to manipulate it. | | [`useSetState`](./docs/useSetState.md) | Manages an object state, merging updates similarly to `this.setState` in class components. | | [`useStateWithHistory`](./docs/useStateWithHistory.md) | Manages state with a history of changes, allowing for undo and redo operations. | | [`useStepper`](./docs/useStepper.md) | Manages state for multi-step forms or wizards. | | [`useToggle`](./docs/useToggle.md) | Manages a boolean state with a toggle function. | ### 2. Side Effects & Lifecycle Hooks that orchestrate effects, logging, and lifecycle nuances beyond vanilla `useEffect`. | Hook | Description | | :--- | :--- | | [`useConditionalEffect`](./docs/useConditionalEffect.md) | A `useEffect` that only runs its callback if a set of conditions are met. | | [`useCustomCompareEffect`](./docs/useCustomCompareEffect.md) | A `useEffect` that uses a custom comparator function for its dependency array. | | [`useDeepCompareEffect`](./docs/useDeepCompareEffect.md) | A `useEffect` that performs a deep comparison of its dependencies. | | [`useDebouncedEffect`](./docs/useDebouncedEffect.md) | A `useEffect` whose callback function is debounced. | | [`useIsomorphicLayoutEffect`](./docs/useIsomorphicLayoutEffect.md) | A hook that uses `useLayoutEffect` in the browser and `useEffect` on the server. | | [`useLifecycleLogger`](./docs/useLifecycleLogger.md) | Logs component lifecycle events (mount, update, unmount) to the console. | | [`useLogger`](./docs/useLogger.md) | Logs component lifecycle events and prop changes. | | [`useMount`](./docs/useMount.md) | Runs a callback function once when the component mounts. | | `useThrottledEffect` | A `useEffect` whose callback function is throttled. | | [`useUnmount`](./docs/useUnmount.md) | Runs a callback function when the component unmounts. | | [`useUnmountEffect`](./docs/useUnmountEffect.md) | Runs an effect only when the component is unmounted. | | [`useUpdateEffect`](./docs/useUpdateEffect.md) | A `useEffect` that skips the initial render and only runs on updates. | | [`useWhyDidYouUpdate`](./docs/useWhyDidYouUpdate.md) | A debugging tool that logs which props changed on a component re-render. | | [`useErrorBoundary`](./docs/useErrorBoundary.md) | Imperative helpers for programmatically triggering and resetting React error boundaries. | | [`useReducerLogger`](./docs/useReducerLogger.md) | Wraps `useReducer` to log every action and resulting state, aiding debugging. | ### 3. Data Fetching Helpers for REST-style data loading, request cancellation, debouncing, and network-aware flows. | Hook | Description | | :--- | :--- | | [`useAsync`](./docs/useAsync.md) | Manages the state of an asynchronous function call. | | [`useAsyncAbortable`](./docs/useAsyncAbortable.md) | An `useAsync` variant that provides an `AbortSignal` to the async function. | | [`useCachedFetch`](./docs/useCachedFetch.md) | A `useFetch` variant with in-memory caching to avoid redundant requests. | | [`useDebouncedFetch`](./docs/useDebouncedFetch.md) | A `useFetch` variant that debounces the request trigger. | | [`useDelete`](./docs/useDelete.md) | A specialized `useFetch` for making DELETE requests. | | [`useFetch`](./docs/useFetch.md) | A general-purpose hook for fetching data from an API. | | [`useGet`](./docs/useGet.md) | A specialized `useFetch` for making GET requests. | | [`useIdleFetch`](./docs/useIdleFetch.md) | Triggers a data fetch when the user becomes active after a period of inactivity. | | [`useLocationBasedFetch`](./docs/useLocationBasedFetch.md) | Fetches data from an API based on the user's current geolocation. | | [`useMutation`](./docs/useMutation.md) | Manages asynchronous operations that modify data (e.g., POST, PUT, DELETE). | | [`useNetworkAwareFetch`](./docs/useNetworkAwareFetch.md) | A `useFetch` variant that only runs when the user is online. | | [`usePatch`](./docs/usePatch.md) | A specialized `useFetch` for making PATCH requests. | | [`usePost`](./docs/usePost.md) | A specialized `useFetch` for making POST requests. | | [`usePromise`](./docs/usePromise.md) | Manages the state of a promise-based function. | | [`usePut`](./docs/usePut.md) | A specialized `useFetch` for making PUT requests. | ### 4. Browser & Web APIs Wrappers around platform APIs such as Clipboard, Storage, Battery, Permissions, and Web Workers. | Hook | Description | | :--- | :--- | | [`useBatteryStatus`](./docs/useBatteryStatus.md) | Tracks the device's battery status using the Battery Status API. | | [`useBroadcastChannel`](./docs/useBroadcastChannel.md) | Enables cross-tab/window communication using the Broadcast Channel API. | | [`useClipboard`](./docs/useClipboard.md) | Interacts with the system clipboard for copying and pasting. | | [`useClipboardWithFeedback`](./docs/useClipboardWithFeedback.md) | An extension of `useClipboard` that provides feedback when text is copied. | | [`useCookie`](./docs/useCookie.md) | Manages a specific browser cookie. | | [`useCopyToClipboard`](./docs/useCopyToClipboard.md) | A hook specifically for copying text to the clipboard. | | [`useDeviceMotion`](./docs/useDeviceMotion.md) | Tracks device motion information like acceleration and rotation rate. | | [`useDeviceOrientation`](./docs/useDeviceOrientation.md) | Tracks the physical orientation of the device. | | [`useDocumentTitle`](./docs/useDocumentTitle.md) | Sets the `document.title` of the page. | | [`useEventSource`](./docs/useEventSource.md) | Connects to a Server-Sent Events (SSE) endpoint. | | [`useEyeDropper`](./docs/useEyeDropper.md) | Uses the experimental EyeDropper API to sample colors from the screen. | | [`useFavicon`](./docs/useFavicon.md) | Dynamically sets the website's favicon. | | [`useFullscreen`](./docs/useFullscreen.md) | Manages the fullscreen state for a specific element. | | [`useGeolocation`](./docs/useGeolocation.md) | Tracks the user's geolocation. | | [`useGeolocationContinuous`](./docs/useGeolocationContinuous.md) | Provides a continuous stream of geolocation data. | | [`useIdleCallback`](./docs/useIdleCallback.md) | Schedules a function to be executed during browser idle periods. | | [`useIdleDetection`](./docs/useIdleDetection.md) | Detects user idle state and screen lock status using the Idle Detection API. | | [`useLocalStorage`](./docs/useLocalStorage.md) | Manages state with `localStorage`, automatically syncing between state and storage. | | [`useLocalStorageQueue`](./docs/useLocalStorageQueue.md) | Manages a queue that is persisted in `localStorage`. | | [`useLocalStorageValue`](./docs/useLocalStorageValue.md) | Manages a single `localStorage` key. | | [`useMediaStream`](./docs/useMediaStream.md) | Manages access to the user's media devices (camera, microphone). | | [`useNetworkAwareWebSocket`](./docs/useNetworkAwareWebSocket.md) | Manages a WebSocket connection that is only active when the user is online. | | [`useNetworkSpeed`](./docs/useNetworkSpeed.md) | Gets information about the user's network connection speed and type. | | [`useNetworkState`](./docs/useNetworkState.md) | Tracks the state of the browser's network connection. | | [`useNotification`](./docs/useNotification.md) | Manages web notifications. | | [`useOnlineStatus`](./docs/useOnlineStatus.md) | Tracks the browser's online status. | | [`useOrientation`](./docs/useOrientation.md) | Tracks the device's screen orientation. | | [`usePageVisibility`](./docs/usePageVisibility.md) | Tracks the visibility state of the browser page/tab. | | [`usePermission`](./docs/usePermission.md) | Queries the status of a browser permission using the Permissions API. | | [`usePersistentCounter`](./docs/usePersistentCounter.md) | A counter that persists its state in `localStorage`. | | [`usePersistentToggle`](./docs/usePersistentToggle.md) | A boolean state that persists in `localStorage`. | | [`usePreferredLanguages`](./docs/usePreferredLanguages.md) | Retrieves the user's preferred languages from the browser. | | [`usePrefersReducedMotion`](./docs/usePrefersReducedMotion.md) | Detects if the user prefers reduced motion. | | [`useQueryParam`](./docs/useQueryParam.md) | Synchronizes a state variable with a URL query parameter. | | [`useScreenOrientation`](./docs/useScreenOrientation.md) | Tracks the screen orientation state. | | [`useScript`](./docs/useScript.md) | Dynamically loads an external script and tracks its loading state. | | [`useSessionStorage`](./docs/useSessionStorage.md) | Manages state with `sessionStorage`, automatically syncing between state and storage. | | [`useSpeechSynthesis`](./docs/useSpeechSynthesis.md) | Utilizes the browser's Speech Synthesis API (Text-to-Speech). | | [`useStorageValue`](./docs/useStorageValue.md) | A generic hook for managing a single key in a `Storage` object. | | [`useSyncedLocalStorage`](./docs/useSyncedLocalStorage.md) | A `useLocalStorage` variant that syncs its state across multiple tabs/windows. | | [`useVibration`](./docs/useVibration.md) | Interacts with the browser's Vibration API. | | [`useWakeLock`](./docs/useWakeLock.md) | Manages a screen wake lock to prevent the device from sleeping. | | [`useWebSocket`](./docs/useWebSocket.md) | Manages WebSocket connections. | | [`useWebWorker`](./docs/useWebWorker.md) | Runs a function in a web worker to avoid blocking the main thread. | | [`useWorker`](./docs/useWorker.md) | Another hook for running functions in a web worker. | | [`useDarkMode`](./docs/useDarkMode.md) | Synchronizes the UI theme with system preferences and persists overrides in `localStorage`. | | [`useDebouncedGeolocation`](./docs/useDebouncedGeolocation.md) | Throttles high-frequency geolocation updates so downstream effects run at a manageable cadence. | ### 5. User Interface & DOM DOM-centric hooks for layout measurements, interactions, viewport tracking, and accessibility patterns. | Hook | Description | | :--- | :--- | | [`useBreakpoint`](./docs/useBreakpoint.md) | Determines the currently active responsive breakpoint. | | [`useClickOutside`](./docs/useClickOutside.md) | Detects clicks outside of a specified element. | | [`useClickOutsideWithEscape`](./docs/useClickOutsideWithEscape.md) | Triggers a callback on a click outside an element or on pressing the 'Escape' key. | | [`useContextMenu`](./docs/useContextMenu.md) | Manages the state for a custom context menu. | | [`useDebouncedMediaQuery`](./docs/useDebouncedMediaQuery.md) | A `useMediaQuery` variant that debounces the result. | | [`useDebouncedWindowSize`](./docs/useDebouncedWindowSize.md) | A `useWindowSize` variant that provides debounced dimensions. | | [`useDrag`](./docs/useDrag.md) | Provides basic drag-and-drop event handling for an element. | | [`useDraggable`](./docs/useDraggable.md) | Makes a DOM element draggable. | | [`useElementSize`](./docs/useElementSize.md) | Observes an element's size and provides its width and height. | | [`useFocusTrap`](./docs/useFocusTrap.md) | Traps focus within a specified container element. | | [`useFocusWithinState`](./docs/useFocusWithinState.md) | Tracks whether an element or any of its descendants has focus. | | [`useHasBeenVisible`](./docs/useHasBeenVisible.md) | Tracks if an element has ever become visible in the viewport. | | [`useHover`](./docs/useHover.md) | Detects whether a DOM element is being hovered over. | | [`useHoverDelay`](./docs/useHoverDelay.md) | Tracks if an element has been hovered for a minimum specified duration. | | [`useImageOnLoad`](./docs/useImageOnLoad.md) | Tracks the loading status and dimensions of an image. | | [`useInfiniteScroll`](./docs/useInfiniteScroll.md) | Implements infinite scrolling. | | [`useIntersectionObserver`](./docs/useIntersectionObserver.md) | Tracks the visibility of an element within the viewport. | | [`useMeasure`](./docs/useMeasure.md) | Tracks element dimensions using `ResizeObserver`. | | [`useMediaQuery`](./docs/useMediaQuery.md) | Tracks the state of a CSS media query. | | [`useMergeRefs`](./docs/useMergeRefs.md) | Merges multiple refs into a single callback ref. | | [`useMobile`](./docs/use-mobile.md) | Returns whether the current viewport is mobile-sized. | | [`useMousePosition`](./docs/useMousePosition.md) | Tracks the current position of the mouse pointer. | | [`usePageLeave`](./docs/usePageLeave.md) | Triggers a callback when the user's mouse cursor leaves the viewport. | | [`usePagination`](./docs/usePagination.md) | Manages pagination state and controls. | | [`usePinchZoom`](./docs/usePinchZoom.md) | Detects pinch-to-zoom gestures on a target element. | | [`usePortal`](./docs/usePortal.md) | Manages a React Portal. | | [`useResizeObserver`](./docs/useResizeObserver.md) | Monitors changes to an element's size using `ResizeObserver`. | | [`useRovingTabIndex`](./docs/useRovingTabIndex.md) | Implements the roving tabindex accessibility pattern. | | [`useScrollLock`](./docs/useScrollLock.md) | Locks and unlocks body scroll. | | [`useScrollPosition`](./docs/useScrollPosition.md) | Tracks the scroll position of the window or a specific element. | | [`useScrollSpy`](./docs/useScrollSpy.md) | Monitors scroll position to determine which element is currently active. | | [`useScrollToTop`](./docs/useScrollToTop.md) | Provides a function to scroll the window to the top. | | [`useSwipe`](./docs/useSwipe.md) | Detects swipe gestures on a target element. | | [`useTextSelection`](./docs/useTextSelection.md) | Tracks the user's text selection within the document. | | [`useVirtualList`](./docs/useVirtualList.md) | Optimizes the rendering of long lists by only rendering visible items. | | [`useVisibility`](./docs/useVisibility.md) | Tracks whether an element is visible in the viewport. | | [`useWindowSize`](./docs/useWindowSize.md) | Tracks the browser window's dimensions. | | [`useHookableRef`](./docs/useHookableRef.md) | Combines refs with callbacks so consumers can observe element mount/unmount events. | | [`useIsomorphicId`](./docs/useIsomorphicId.md) | Creates a stable ID that works consistently in SSR and CSR environments. | ### 6. Event Handling Utilities that simplify attaching listeners, key combos, long presses, and history changes. | Hook | Description | | :--- | :--- | | [`useEventListener`](./docs/useEventListener.md) | Attaches an event listener to a target element. | | [`useEventCallback`](./docs/useEventCallback.md) | Creates a stable callback function that always calls the latest version of the provided callback. | | [`useKeyCombo`](./docs/useKeyCombo.md) | Detects specific keyboard combinations (shortcuts). | | [`useKeyPress`](./docs/useKeyPress.md) | Detects when a specific key is pressed down. | | [`useLongPress`](./docs/useLongPress.md) | Detects long press events on an element. | | [`useRouteChange`](./docs/useRouteChange.md) | Executes a callback when the browser's route changes. | | [`useThrottledEventListener`](./docs/useThrottledEventListener.md) | Attaches an event listener with a throttled callback. | ### 7. Performance & Optimization Debounce/throttle utilities, RAF helpers, and render diagnostics that keep components snappy. | Hook | Description | | :--- | :--- | | [`useDebounce`](./docs/useDebounce.md) | Debounces a value, delaying its update until a specified time has passed without change. | | [`useDebouncedCallback`](./docs/useDebouncedCallback.md) | Creates a debounced version of a callback function. | | [`useDebouncedState`](./docs/useDebouncedState.md) | A `useState` variant where the state updates are debounced. | | [`useForceUpdate`](./docs/useForceUpdate.md) | Provides a function to manually force a component to re-render. | | [`useRafCallback`](./docs/useRafCallback.md) | Schedules a callback to be executed on the next animation frame. | | [`useRafState`](./docs/useRafState.md) | A `useState` variant that updates state on the next animation frame. | | [`useRenderCount`](./docs/useRenderCount.md) | Tracks the number of times a component has rendered. | | [`useRerender`](./docs/useRerender.md) | Provides a function to manually trigger a re-render. | | [`useThrottle`](./docs/useThrottle.md) | Throttles a value, ensuring it updates at most once per specified interval. | | [`useThrottledCallback`](./docs/useThrottledCallback.md) | Creates a throttled version of a callback function. | | [`useThrottledScroll`](./docs/useThrottledScroll.md) | Tracks window scroll position with throttled updates. | | [`useThrottledState`](./docs/useThrottledState.md) | A `useState` variant where state updates are throttled. | | [`useCustomCompareMemo`](./docs/useCustomCompareMemo.md) | Memo variant that reruns its factory only when a custom comparator reports dependency changes. | | [`useSyncedRef`](./docs/useSyncedRef.md) | Keeps a mutable ref in sync with the latest value without re-rendering consumers. | ### 8. Forms Form-centric hooks for managing inputs, validation, and lightweight i18n. | Hook | Description | | :--- | :--- | | [`useForm`](./docs/useForm.md) | Manages form state, input changes, and submission handling. | | [`useFormValidation`](./docs/useFormValidation.md) | Manages form state with built-in validation and submission logic. | | [`useTranslation`](./docs/useTranslation.md) | A basic internationalization (i18n) hook for translating form labels and messages. | ### 9. Timers & Intervals Declarative abstractions over `setTimeout` and `setInterval`, including countdowns and idle timers. | Hook | Description | | :--- | :--- | | [`useCountdown`](./docs/useCountdown.md) | Manages a countdown timer with start, pause, and reset controls. | | [`useIdleTimer`](./docs/useIdleTimer.md) | Detects user inactivity. | | [`useInterval`](./docs/useInterval.md) | Sets up an interval that repeatedly calls a function. | | [`useIntervalWhen`](./docs/useIntervalWhen.md) | An `useInterval` variant that only runs when a specific condition is true. | | [`useTimeout`](./docs/useTimeout.md) | Sets up a timeout that calls a function after a delay. | ### 10. Animation Hooks powered by `requestAnimationFrame` for smooth motion primitives. | Hook | Description | | :--- | :--- | | [`useAnimation`](./docs/useAnimation.md) | Manages a basic animation loop using `requestAnimationFrame`. | | [`useAnimationFrame`](./docs/useAnimationFrame.md) | Runs a callback function repeatedly using `requestAnimationFrame`. |