CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-mantine--hooks

A comprehensive collection of 75+ React hooks for state and UI management including storage, events, browser APIs, and performance optimizations

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

timing.mddocs/

Timing & Performance

Performance optimization hooks including debouncing, throttling, intervals, timeouts, and callback optimization for efficient React applications.

Capabilities

useInterval

Declarative intervals with start/stop/toggle controls and automatic cleanup.

/**
 * Declarative interval with controls
 * @param fn - Function to execute on interval
 * @param interval - Interval duration in milliseconds
 * @param options - Configuration for auto-invoke
 * @returns Object with interval controls and state
 */
function useInterval(fn: () => void, interval: number, options?: UseIntervalOptions): UseIntervalReturnValue;

interface UseIntervalOptions {
  autoInvoke?: boolean; // Start interval immediately (default: false)
}

interface UseIntervalReturnValue {
  start: () => void;
  stop: () => void;
  toggle: () => void;
  active: boolean;
}

Usage Examples:

import { useInterval } from "@mantine/hooks";

function Timer() {
  const [seconds, setSeconds] = useState(0);
  
  const interval = useInterval(() => {
    setSeconds(s => s + 1);
  }, 1000);
  
  return (
    <div>
      <p>Seconds: {seconds}</p>
      <button onClick={interval.toggle}>
        {interval.active ? 'Pause' : 'Start'}
      </button>
      <button onClick={() => setSeconds(0)}>Reset</button>
    </div>
  );
}

// Auto-start interval
function AutoTimer() {
  const [count, setCount] = useState(0);
  
  useInterval(() => {
    setCount(c => c + 1);
  }, 1000, { autoInvoke: true });
  
  return <div>Count: {count}</div>;
}

useTimeout

Declarative timeout with start/clear controls.

/**
 * Declarative timeout with controls
 * @param callback - Function to execute after delay
 * @param delay - Delay in milliseconds
 * @param options - Configuration for auto-invoke
 * @returns Object with timeout controls
 */
function useTimeout(callback: () => void, delay: number, options?: UseTimeoutOptions): UseTimeoutReturnValue;

interface UseTimeoutOptions {
  autoInvoke?: boolean; // Start timeout immediately (default: false)
}

interface UseTimeoutReturnValue {
  start: () => void;
  clear: () => void;
}

useDebouncedCallback

Debounced callback with cancel/flush/pending methods and advanced options.

/**
 * Debounced callback with advanced controls
 * @param callback - Function to debounce
 * @param delay - Debounce delay in milliseconds
 * @param options - Debounce configuration
 * @returns Debounced function with control methods
 */
function useDebouncedCallback<T extends (...args: any[]) => any>(
  callback: T,
  delay: number,
  options?: UseDebouncedCallbackOptions
): UseDebouncedCallbackReturnValue<T>;

interface UseDebouncedCallbackOptions {
  maxWait?: number; // Maximum time to wait before forcing execution
  leading?: boolean; // Execute on leading edge
  trailing?: boolean; // Execute on trailing edge (default: true)
}

type UseDebouncedCallbackReturnValue<T> = T & {
  cancel: () => void;
  flush: () => void;
  pending: () => boolean;
};

Usage Examples:

import { useDebouncedCallback } from "@mantine/hooks";

function SearchInput() {
  const [query, setQuery] = useState('');
  
  const handleSearch = useDebouncedCallback((searchQuery: string) => {
    // API call
    console.log('Searching for:', searchQuery);
  }, 500, {
    leading: false,
    trailing: true
  });
  
  useEffect(() => {
    if (query) {
      handleSearch(query);
    } else {
      handleSearch.cancel(); // Cancel pending search
    }
  }, [query, handleSearch]);
  
  return (
    <div>
      <input 
        value={query} 
        onChange={(e) => setQuery(e.target.value)} 
        placeholder="Search..."
      />
      <button onClick={() => handleSearch.flush()}>
        Search Now
      </button>
      <p>Pending: {handleSearch.pending() ? 'Yes' : 'No'}</p>
    </div>
  );
}

useDebouncedState

State with debounced updates to reduce re-renders.

/**
 * State with debounced updates
 * @param defaultValue - Initial state value
 * @param wait - Debounce delay in milliseconds
 * @param options - Debounce configuration
 * @returns Tuple of debounced value and setter
 */
function useDebouncedState<T>(defaultValue: T, wait: number, options?: UseDebouncedStateOptions): UseDebouncedStateReturnValue<T>;

interface UseDebouncedStateOptions {
  leading?: boolean; // Update on leading edge
}

type UseDebouncedStateReturnValue<T> = [T, React.Dispatch<React.SetStateAction<T>>];

useDebouncedValue

Debounced value updates for derived state.

/**
 * Debounced value updates
 * @param value - Value to debounce
 * @param wait - Debounce delay in milliseconds
 * @param options - Debounce configuration
 * @returns Tuple of debounced value and cancel function
 */
function useDebouncedValue<T>(value: T, wait: number, options?: UseDebouncedValueOptions): UseDebouncedValueReturnValue<T>;

interface UseDebouncedValueOptions {
  leading?: boolean;
}

type UseDebouncedValueReturnValue<T> = [T, () => void];

Usage Examples:

import { useDebouncedValue } from "@mantine/hooks";

function ExpensiveComponent({ searchQuery }: { searchQuery: string }) {
  const [debouncedQuery, cancel] = useDebouncedValue(searchQuery, 300);
  
  // Only re-compute when debounced value changes
  const expensiveResults = useMemo(() => {
    return performExpensiveSearch(debouncedQuery);
  }, [debouncedQuery]);
  
  return (
    <div>
      <p>Searching for: {debouncedQuery}</p>
      <button onClick={cancel}>Cancel Search</button>
      <Results data={expensiveResults} />
    </div>
  );
}

useThrottledCallback

Throttled callback execution to limit call frequency.

/**
 * Throttled callback execution
 * @param callback - Function to throttle
 * @param wait - Throttle delay in milliseconds
 * @returns Throttled function
 */
function useThrottledCallback<T extends (...args: any[]) => any>(
  callback: T,
  wait: number
): T;

useThrottledState

State with throttled updates to limit update frequency.

/**
 * State with throttled updates
 * @param defaultValue - Initial state value
 * @param wait - Throttle delay in milliseconds
 * @returns Tuple of throttled value and setter
 */
function useThrottledState<T>(defaultValue: T, wait: number): [T, React.Dispatch<React.SetStateAction<T>>];

useThrottledValue

Throttled value updates for performance optimization.

/**
 * Throttled value updates
 * @param value - Value to throttle
 * @param wait - Throttle delay in milliseconds
 * @returns Throttled value
 */
function useThrottledValue<T>(value: T, wait: number): T;

Usage Examples:

import { useThrottledValue, useThrottledCallback } from "@mantine/hooks";

function ScrollHandler() {
  const [scrollY, setScrollY] = useState(0);
  
  // Throttle scroll updates for performance
  const throttledScrollY = useThrottledValue(scrollY, 100);
  
  const handleScroll = useThrottledCallback(() => {
    setScrollY(window.scrollY);
  }, 16); // ~60fps
  
  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, [handleScroll]);
  
  return <div>Scroll position: {throttledScrollY}</div>;
}

Performance Patterns

Search Optimization

import { useDebouncedCallback, useDebouncedValue } from "@mantine/hooks";

function OptimizedSearch() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [loading, setLoading] = useState(false);
  
  // Debounce the search function
  const debouncedSearch = useDebouncedCallback(async (searchTerm: string) => {
    if (!searchTerm.trim()) {
      setResults([]);
      return;
    }
    
    setLoading(true);
    try {
      const response = await searchAPI(searchTerm);
      setResults(response.data);
    } finally {
      setLoading(false);
    }
  }, 300);
  
  // Alternative: debounce the value
  const [debouncedQuery] = useDebouncedValue(query, 300);
  
  useEffect(() => {
    debouncedSearch(query);
  }, [query, debouncedSearch]);
  
  return (
    <div>
      <input 
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="Search..."
      />
      {loading && <div>Searching...</div>}
      <SearchResults results={results} />
    </div>
  );
}

Animation Control

import { useInterval, useTimeout } from "@mantine/hooks";

function AnimationController() {
  const [progress, setProgress] = useState(0);
  const [isPlaying, setIsPlaying] = useState(false);
  
  const animation = useInterval(() => {
    setProgress(p => {
      if (p >= 100) {
        animation.stop();
        setIsPlaying(false);
        return 100;
      }
      return p + 1;
    });
  }, 50);
  
  const resetTimeout = useTimeout(() => {
    setProgress(0);
  }, 1000);
  
  const startAnimation = () => {
    setIsPlaying(true);
    animation.start();
  };
  
  const resetAnimation = () => {
    animation.stop();
    setIsPlaying(false);
    resetTimeout.start();
  };
  
  return (
    <div>
      <div style={{ width: `${progress}%`, height: '20px', background: 'blue' }} />
      <button onClick={startAnimation} disabled={isPlaying}>
        Start
      </button>
      <button onClick={resetAnimation}>
        Reset
      </button>
    </div>
  );
}

docs

browser-apis.md

device.md

dom-events.md

index.md

navigation.md

network.md

observers.md

specialized.md

state-management.md

storage.md

timing.md

utilities.md

tile.json