Snippets
React logo

React

Small, dependency-free React hooks and patterns. Copy, paste, and ship with no npm package, no version pinning, no surprises.

8

Server Action with Zod Validation and useActionState

A type-safe Next.js Server Action validated with Zod, wired to a form via useActionState for inline error rendering.

reactnextjsserver-actions+2
INTERMEDIATEApr 28, 2026

useClickOutside Hook for React

A typed React hook that fires a callback when the user clicks outside a referenced element. Perfect for closing dropdowns and modals.

reacthooksref+2
BEGINNERMay 18, 2026

useCopyToClipboard Hook for React

A typed React hook that copies any string to the clipboard with a success state, error handling, and an automatic reset timer.

reacthooksclipboard+2
BEGINNERApr 18, 2026

useDebounce Hook for React

A typed React useDebounce hook that delays value updates until the user stops changing them. SSR-safe, auto-cleanup, fully typed.

reacthooksdebounce+2
BEGINNERApr 6, 2026

useIntersectionObserver Hook for React

A performant, TypeScript-safe React hook wrapping IntersectionObserver. Ideal for fade-in-on-scroll, lazy loading, and infinite scroll.

reacthooksintersection-observer+3
INTERMEDIATEDec 1, 2025

useLocalStorage Hook

Reactive wrapper over browser localStorage that keeps React state persisted, cross-tab aware, and SSR safe.

reacthookslocalstorage+1
INTERMEDIATEOct 16, 2025

useOnlineStatus Hook for React

A typed React hook that tracks the browser online/offline state and re-renders components when the network status changes.

reacthooksonline+2
BEGINNERMay 8, 2026

useScrollProgress Hook for React

A tiny, SSR-safe React hook that tracks vertical scroll progress as a 0 to 1 value. Perfect for reading progress bars and scroll-linked effects.

reacthooksscroll+3
BEGINNERDec 1, 2025

About these React snippets

This is a collection of the React hooks and helpers I actually reuse across real Next.js apps, including this portfolio. Everything here is TypeScript-first, SSR-safe where it matters, and written to work with modern React (18 and 19) and the Next.js App Router. No class components, no legacy patterns.

Each snippet is deliberately tiny: usually 30 to 80 lines of code you can read in one pass, understand, and paste straight into your project. There is no @rabi/react-utils package to install, because experience has taught me that the best small utilities are the ones you own outright. You can tweak them, delete them, or grow them without fighting a maintainer's opinion.

What's inside

  • useDebounce: debounce any rapidly changing value (search inputs, resize events, filters) with a single line of code.
  • useIntersectionObserver: declarative viewport tracking for fade-in animations, lazy loading, and infinite scroll.
  • useScrollProgress: a passive scroll-progress hook for reading progress bars and scroll-linked effects.
  • useLocalStorage: typed, SSR-safe state that persists to localStorage, with cross-tab sync.
  • useClickOutside, useCopyToClipboard, useKeyboardShortcut, useOnlineStatus: the small hooks you end up needing on nearly every project.

More hooks land here as I extract them from client work and this site's own components. If you are curious about what is coming next, the blog usually covers the deeper "why" behind a hook before it shows up here.

How to use them

Every snippet page shows the full source plus a minimal usage example. Copy the hook, drop it in src/hooks/, and import it. That is the whole workflow. The code is intentionally small enough to read in under a minute, so you can adapt it to your own naming conventions, styling system, or state library without fighting a generic API.

A few things I try to get right on every hook:

  • SSR safety: every hook guards window, document, and localStorage access so it does not break Next.js server rendering or hydration.
  • Cleanup: event listeners and observers are always torn down in the useEffect cleanup, so there is no memory leak when a component unmounts.
  • Passive listeners: scroll and touch handlers use { passive: true } whenever they do not call preventDefault, so the main thread stays free.

If you spot a bug or a cleaner version, the code is open on GitHub. Issues and PRs are welcome.