reactives-hooks
v0.1.1
Published
A collection of useful React hooks and utilities for React and Next.js
Maintainers
Readme
reactives-hooks
A collection of useful React hooks and utilities for React and Next.js.
- TypeScript-first — Full type safety with generics
- Tree-shakeable — Import only what you need
- SSR-safe — Works with Next.js SSR/SSG out of the box
- Zero dependencies — No bloat (except
cnutil which usesclsx+tailwind-merge) - React 18+ compatible (React 19 ready)
Install
npm install reactives-hooks
# or
pnpm add reactives-hooks
# or
yarn add reactives-hooksUsage
import { useToggle, useLocalStorage, useDebounceValue } from 'reactives-hooks'
import { useQueryParams } from 'reactives-hooks/next'
import { cn } from 'reactives-hooks/utils'
function App() {
const [isOpen, toggle] = useToggle(false)
const [theme, setTheme] = useLocalStorage('theme', 'light')
const debouncedSearch = useDebounceValue(search, 300)
return (
<div className={cn('container', isOpen && 'open')}>
<button onClick={toggle}>Toggle</button>
</div>
)
}Hooks
State
useToggle
Toggles a boolean value.
const [isOpen, toggle] = useToggle(false)
toggle() // true
toggle(false) // falseuseBoolean
Provides explicit boolean control methods.
const { value: isOpen, setTrue: open, setFalse: close, toggle } = useBoolean(false)useCounter
Numeric counter with min/max bounds.
const [count, { increment, decrement, reset }] = useCounter(0, { min: 0, max: 100 })useMap
Manages Map data structure state.
const [map, { set, delete: remove, clear }] = useMap<string, string>([['key', 'value']])useSet
Manages Set data structure state.
const [set, { add, toggle, clear }] = useSet<string>(['react'])usePrevious
Returns the value from the previous render.
const prevCount = usePrevious(count) // undefined on first renderuseStateHistory
State management with undo/redo support.
const { value, set, undo, redo, canUndo, canRedo } = useStateHistory('')Storage
useLocalStorage
Manages state synced with localStorage.
const [theme, setTheme, removeTheme] = useLocalStorage('theme', 'light')useSessionStorage
Manages state synced with sessionStorage.
const [draft, setDraft, clearDraft] = useSessionStorage('form-draft', '')DOM
useEventListener
Registers a type-safe event listener.
useEventListener('keydown', (e) => console.log(e.key))
useEventListener('click', handler, elementRef)useClickOutside
Detects clicks outside an element.
const ref = useClickOutside<HTMLDivElement>(() => setIsOpen(false))useHover
Tracks hover state of an element.
const [hoverRef, isHovered] = useHover<HTMLDivElement>()useIntersectionObserver
Detects viewport intersection of an element.
const { ref, isIntersecting } = useIntersectionObserver({ freezeOnceVisible: true })useResizeObserver
Detects element size changes.
const [ref, { width, height }] = useResizeObserver<HTMLDivElement>()useMutationObserver
Detects DOM mutations.
const ref = useMutationObserver((mutations) => { /* ... */ })Sensor
useMediaQuery
Tracks CSS media query match state.
const isMobile = useMediaQuery('(max-width: 768px)')useWindowSize
Tracks browser window dimensions.
const { width, height } = useWindowSize()useScroll
Tracks scroll position.
const { x, y } = useScroll()useMouse
Tracks mouse cursor position.
const { x, y } = useMouse()useNetwork
Tracks network status and connection info.
const { online, effectiveType, downlink } = useNetwork()Performance
useDebounceValue
Debounces a value update.
const debouncedSearch = useDebounceValue(search, 300)useDebounceCallback
Debounces a callback function.
const save = useDebounceCallback((content: string) => api.save(content), 1000)useThrottleValue
Throttles a value update.
const throttledY = useThrottleValue(scrollY, 100)useThrottleCallback
Throttles a callback function.
const track = useThrottleCallback((x, y) => analytics.track(x, y), 200)Lifecycle
useMount
Runs a callback on component mount.
useMount(() => analytics.pageView())useUnmount
Runs a callback on component unmount.
useUnmount(() => clearInterval(timer))useUpdateEffect
A useEffect that skips the first render.
useUpdateEffect(() => {
fetchResults(query)
}, [query])useIsMounted
Checks component mount status.
const isMounted = useIsMounted()
if (isMounted()) setData(result)useIsomorphicLayoutEffect
SSR-safe useLayoutEffect.
useIsomorphicLayoutEffect(() => {
// useLayoutEffect on browser, useEffect on server
}, [])useDeepCompareEffect
A useEffect with deep comparison of dependencies.
useDeepCompareEffect(() => {
fetchUsers(filters)
}, [filters])UI
useScrollLock
Locks body scroll.
useScrollLock(isModalOpen)useDarkMode
Manages dark mode with system preference support.
const { isDark, theme, setTheme, toggle } = useDarkMode('system')useFullscreen
Wraps the Fullscreen API.
const { ref, isFullscreen, toggle } = useFullscreen()useCopyToClipboard
Copies text to the clipboard.
const { copiedText, copy } = useCopyToClipboard()
await copy('Hello!')useHotkeys
Binds keyboard shortcuts.
useHotkeys('ctrl+s', () => save())
useHotkeys('cmd+k', () => openPalette())Data
useAsync
Wraps an async function with loading/error states.
const { data, loading, error, execute } = useAsync(() => fetchUser(id))useFetch
Fetch wrapper with abort support.
const { data, loading, error, refetch } = useFetch<Post[]>('/api/posts')useInfiniteScroll
IntersectionObserver-based infinite scroll.
const { sentinelRef, loading } = useInfiniteScroll(loadMore, hasMore)usePagination
Manages pagination logic.
const { page, totalPages, next, prev, hasNext } = usePagination({
totalItems: 100,
pageSize: 20,
})Next.js (reactives-hooks/next)
useQueryParams
Manages type-safe URL query parameters.
const { params, set, delete: remove } = useQueryParams<{ q: string; sort: string }>()
set('q', 'react')useRouteChange
Detects route changes.
useRouteChange({ onComplete: (url) => analytics.pageView(url) })useSafeAction
Safely executes Server Actions.
const { execute, data, loading, error } = useSafeAction(createPost)useIsServer
Detects server/client rendering environment.
const isServer = useIsServer() // true on server, false on clientUtils (reactives-hooks/utils)
cn
Conditionally merges Tailwind CSS classes.
cn('px-2 py-1', isActive && 'bg-blue-500', className)formatDate
Formats a date with locale support.
formatDate(new Date(), { year: 'numeric', month: 'long', day: 'numeric' }, 'ko-KR')sleep
Promise-based delay function.
await sleep(1000) // Wait 1 secondLicense
MIT
