hooks

javascript
import { useCallback, useEffect, useRef, useState } from 'react';

export function usePaginatedFetch(fetchPage, { pageSize = 20 } = {}) {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

Infinite Scroll in React with IntersectionObserver and a Paginated Fetch Hook

react hooks infinite-scroll
by codesnips 3 tabs
typescript
import { useMemo } from "react";

export type SortDir = "asc" | "desc";
export interface SortConfig<T> {
  key: keyof T;
  dir: SortDir;

Memoized Async Search With a Cached Selector Hook in React

react hooks usememo
by codesnips 3 tabs
javascript
import { useEffect, useState } from "react";

export function useDebouncedValue(value, delay = 300) {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {

Debounced Search Input in React with a Reusable useDebouncedValue Hook

react hooks debounce
by codesnips 3 tabs
javascript
export const initialCart = { items: {} };

export function cartReducer(state, action) {
  switch (action.type) {
    case 'ADD_ITEM': {
      const { product, qty = 1 } = action;

Persist and Hydrate a Shopping Cart with useReducer and localStorage

react hooks usereducer
by codesnips 3 tabs
javascript
import { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { fetchCurrentUser, postLogin, postLogout } from './api';

const AuthContext = createContext(null);

export function AuthProvider({ children }) {

Protecting React Routes with an Auth Context and a RequireAuth Wrapper

react react-router authentication
by codesnips 4 tabs
javascript
const BASE_URL = "/api/search";

export async function searchProducts(query, { signal } = {}) {
  const params = new URLSearchParams({ q: query, limit: "10" });
  const res = await fetch(`${BASE_URL}?${params}`, {
    signal,

Cancel Stale Autocomplete Requests with AbortController in a React Hook

react hooks abortcontroller
by codesnips 3 tabs
typescript
import { useCallback, useEffect, useReducer } from "react";

type State = { secondsLeft: number; isRunning: boolean };
type Action =
  | { type: "start"; seconds: number }
  | { type: "tick" }

Resend-Code Button With a Countdown Timer Using useEffect Cleanup

react hooks useeffect
by codesnips 3 tabs
javascript
export const MAX_VISIBLE = 4;

const DEFAULTS = {
  variant: "info",
  duration: 4000,
};

Toast Notification Queue in React with Context and useReducer

react context-api usereducer
by codesnips 3 tabs
typescript
export interface UseClipboardResult {
  copied: boolean;
  error: Error | null;
  copy: (value: string) => Promise<boolean>;
}

Copy-to-Clipboard Button With a useClipboard Hook and Timed Success Feedback

react hooks clipboard
by codesnips 3 tabs
typescript
export interface Todo {
  id: string;
  title: string;
  done: boolean;
  pending: boolean;
}

Optimistic To-Do Toggle in React with Rollback via useReducer

react optimistic-ui hooks
by codesnips 3 tabs
typescript
import { useEffect, useRef } from "react";

const FOCUSABLE = [
  "a[href]",
  "button:not([disabled])",
  "textarea:not([disabled])",

Trap Keyboard Focus in a Modal with a useFocusTrap React Hook

react hooks accessibility
by codesnips 3 tabs
typescript
import { z } from 'zod';

export const signupSchema = z
  .object({
    email: z.string().min(1, 'Email is required').email('Enter a valid email'),
    password: z

React Hook Form + Zod resolver

react forms react-hook-form
by codesnips 3 tabs