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

utilities.mddocs/

Lifecycle & Utilities

React lifecycle utilities and helper hooks for component lifecycle management, ref handling, and common utility patterns.

Capabilities

useForceUpdate

Force component re-render when needed.

/**
 * Force component re-render
 * @returns Function to trigger re-render
 */
function useForceUpdate(): () => void;

Usage Examples:

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

function ComponentWithExternalState() {
  const forceUpdate = useForceUpdate();
  
  // Force update when external state changes
  useEffect(() => {
    const unsubscribe = externalStore.subscribe(() => {
      forceUpdate();
    });
    return unsubscribe;
  }, [forceUpdate]);
  
  return <div>{externalStore.getValue()}</div>;
}

useId

Generate unique IDs with SSR support and optional static override.

/**
 * Generate unique IDs with SSR support
 * @param staticId - Static ID to use instead of generated one
 * @returns Unique ID string
 */
function useId(staticId?: string): string;

Usage Examples:

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

function FormField({ label, staticId }: { label: string; staticId?: string }) {
  const id = useId(staticId);
  
  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input id={id} />
    </div>
  );
}

// Multiple IDs in same component
function MultiFieldForm() {
  const nameId = useId();
  const emailId = useId();
  
  return (
    <form>
      <label htmlFor={nameId}>Name</label>
      <input id={nameId} />
      
      <label htmlFor={emailId}>Email</label>
      <input id={emailId} />
    </form>
  );
}

useMounted

Track component mount state.

/**
 * Track component mount state
 * @returns Boolean indicating if component is mounted
 */
function useMounted(): boolean;

Usage Examples:

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

function AsyncComponent() {
  const [data, setData] = useState(null);
  const mounted = useMounted();
  
  useEffect(() => {
    fetchData().then(result => {
      // Only update state if component is still mounted
      if (mounted) {
        setData(result);
      }
    });
  }, [mounted]);
  
  return <div>{data ? 'Loaded' : 'Loading...'}</div>;
}

useIsFirstRender

Detect if current render is the first render.

/**
 * Detect first render
 * @returns Boolean indicating if this is the first render
 */
function useIsFirstRender(): boolean;

Usage Examples:

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

function AnimatedComponent() {
  const isFirstRender = useIsFirstRender();
  
  return (
    <div 
      className={isFirstRender ? 'no-animation' : 'with-animation'}
    >
      Content
    </div>
  );
}

usePrevious

Access the previous value of a variable.

/**
 * Access previous value
 * @param value - Current value
 * @returns Previous value or undefined on first render
 */
function usePrevious<T>(value: T): T | undefined;

Usage Examples:

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

function Counter() {
  const [count, setCount] = useState(0);
  const previousCount = usePrevious(count);
  
  return (
    <div>
      <p>Current: {count}</p>
      <p>Previous: {previousCount ?? 'None'}</p>
      <button onClick={() => setCount(c => c + 1)}>
        Increment
      </button>
    </div>
  );
}

// Track prop changes
function UserProfile({ userId }: { userId: string }) {
  const previousUserId = usePrevious(userId);
  
  useEffect(() => {
    if (previousUserId && previousUserId !== userId) {
      console.log(`User changed from ${previousUserId} to ${userId}`);
    }
  }, [userId, previousUserId]);
  
  return <div>User ID: {userId}</div>;
}

useDidUpdate

Effect that skips the first render (componentDidUpdate equivalent).

/**
 * Effect that skips first render
 * @param fn - Effect function
 * @param dependencies - Dependency array
 */
function useDidUpdate(fn: React.EffectCallback, dependencies?: React.DependencyList): void;

Usage Examples:

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

function SearchComponent({ query }: { query: string }) {
  const [results, setResults] = useState([]);
  
  // Only run search on updates, not on mount
  useDidUpdate(() => {
    if (query) {
      searchAPI(query).then(setResults);
    }
  }, [query]);
  
  return <SearchResults results={results} />;
}

useIsomorphicEffect

useLayoutEffect in browser, useEffect in SSR environments.

/**
 * Isomorphic effect (useLayoutEffect in browser, useEffect in SSR)
 * @param effect - Effect function
 * @param deps - Dependency array
 */
function useIsomorphicEffect(effect: React.EffectCallback, deps?: React.DependencyList): void;

useShallowEffect

Effect with shallow dependency comparison instead of reference equality.

/**
 * Effect with shallow dependency comparison
 * @param callback - Effect function
 * @param dependencies - Dependency array (compared shallowly)
 */
function useShallowEffect(callback: React.EffectCallback, dependencies: React.DependencyList): void;

Usage Examples:

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

function ObjectDependentComponent({ config }: { config: Config }) {
  const [data, setData] = useState(null);
  
  // Only re-run when config properties change, not reference
  useShallowEffect(() => {
    fetchDataWithConfig(config).then(setData);
  }, [config]);
  
  return <div>{data}</div>;
}

useMergedRef

Merge multiple refs into a single ref callback.

/**
 * Merge multiple refs into single ref callback
 * @param refs - Array of refs to merge
 * @returns Single ref callback
 */
function useMergedRef<T>(...refs: React.Ref<T>[]): React.RefCallback<T | null>;

/**
 * Merge refs utility function
 * @param refs - Array of refs to merge
 * @returns Single ref callback
 */
function mergeRefs<T>(...refs: React.Ref<T>[]): React.RefCallback<T | null>;

/**
 * Assign value to ref utility
 * @param ref - Ref to assign to
 * @param value - Value to assign
 */
function assignRef<T>(ref: React.Ref<T> | undefined, value: T): void;

Usage Examples:

import { useMergedRef } from "@mantine/hooks";
import { useRef, forwardRef } from "react";

// Merge internal ref with forwarded ref
const CustomInput = forwardRef<HTMLInputElement, Props>((props, forwardedRef) => {
  const internalRef = useRef<HTMLInputElement>(null);
  const mergedRef = useMergedRef(internalRef, forwardedRef);
  
  useEffect(() => {
    // Use internal ref for internal logic
    if (internalRef.current) {
      internalRef.current.focus();
    }
  }, []);
  
  return <input ref={mergedRef} {...props} />;
});

// Merge multiple hook refs
function MultiRefComponent() {
  const hoverRef = useHover().ref;
  const clickOutsideRef = useClickOutside(() => {});
  const focusWithinRef = useFocusWithin().ref;
  
  const mergedRef = useMergedRef(hoverRef, clickOutsideRef, focusWithinRef);
  
  return <div ref={mergedRef}>Multiple behaviors</div>;
}

Utility Functions

Core utility functions exported by the package.

/**
 * Clamp value between min and max
 * @param value - Value to clamp
 * @param min - Minimum value
 * @param max - Maximum value
 * @returns Clamped value
 */
function clamp(value: number, min: number, max: number): number;

/**
 * Generate random ID string
 * @returns Random ID
 */
function randomId(): string;

/**
 * Create array of numbers in range
 * @param start - Start number (inclusive)
 * @param end - End number (exclusive)
 * @returns Array of numbers
 */
function range(start: number, end: number): number[];

/**
 * Shallow equality comparison
 * @param a - First value
 * @param b - Second value
 * @returns Boolean indicating shallow equality
 */
function shallowEqual(a: any, b: any): boolean;

/**
 * Convert first character to uppercase
 * @param string - Input string
 * @returns String with first character uppercased
 */
function upperFirst(string: string): string;

/**
 * Convert first character to lowercase
 * @param string - Input string
 * @returns String with first character lowercased
 */
function lowerFirst(string: string): string;

/**
 * Ref callback hook utility
 * @param callback - Callback to convert to ref
 * @returns Ref callback
 */
function useCallbackRef<T>(callback: T | undefined): T;

Usage Examples:

import { clamp, randomId, range, shallowEqual, upperFirst } from "@mantine/hooks";

// Mathematical utilities
const percentage = clamp(userInput, 0, 100); // Ensure 0-100 range
const numbers = range(1, 10); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

// String utilities
const title = upperFirst('hello world'); // "Hello world"

// Comparison
const hasChanged = !shallowEqual(prevProps, nextProps);

// Unique IDs
const elementId = randomId(); // "mantine-r4nd0m1d"

Common Patterns

Ref Management

import { useMergedRef, useCallbackRef } from "@mantine/hooks";

function ComplexComponent({ onResize, onClick }: Props) {
  const resizeRef = useResizeObserver(onResize);
  const clickRef = useClickOutside(onClick);
  const internalRef = useRef<HTMLDivElement>(null);
  
  // Merge all refs
  const mergedRef = useMergedRef(resizeRef, clickRef, internalRef);
  
  return <div ref={mergedRef}>Complex component</div>;
}

Lifecycle Management

import { useMounted, useDidUpdate, usePrevious } from "@mantine/hooks";

function DataComponent({ dataId }: { dataId: string }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const mounted = useMounted();
  const previousDataId = usePrevious(dataId);
  
  // Load data on mount
  useEffect(() => {
    loadData(dataId);
  }, []);
  
  // Reload data when ID changes (skip first render)
  useDidUpdate(() => {
    if (previousDataId !== dataId) {
      loadData(dataId);
    }
  }, [dataId, previousDataId]);
  
  const loadData = async (id: string) => {
    setLoading(true);
    try {
      const result = await fetchData(id);
      if (mounted) {
        setData(result);
      }
    } finally {
      if (mounted) {
        setLoading(false);
      }
    }
  };
  
  return loading ? <div>Loading...</div> : <div>{data}</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