or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

coordinates.mdcss-utilities.mdevent-handling.mdexecution-context.mdfocus-management.mdhooks.mdindex.mdmath-operations.mdtype-guards.mdtypescript-utilities.md
tile.json

hooks.mddocs/

React Hooks

Essential React hooks for building drag and drop interfaces, including ref management, event handling, layout effects, performance optimization, and state management utilities.

Required React Types

These React types are used in the hooks below:

import { DependencyList, MutableRefObject } from 'react';

Capabilities

useCombinedRefs

Combines multiple callback refs into a single ref callback. Useful when you need to pass a ref to multiple hooks or components.

/**
 * Combines multiple callback refs into a single ref callback
 * @param refs - Variable number of callback refs that accept a node
 * @returns A memoized callback function that calls all provided refs with the same node
 */
function useCombinedRefs<T>(...refs: ((node: T) => void)[]): (node: T) => void;

Usage Example:

import React, { useRef, useCallback } from "react";
import { useCombinedRefs } from "@dnd-kit/utilities";

function MyComponent() {
  const myRef = useRef<HTMLDivElement>(null);
  const anotherRef = useCallback((node: HTMLDivElement | null) => {
    if (node) {
      // Do something with the node
      console.log("Element attached:", node);
    }
  }, []);
  
  const combinedRef = useCombinedRefs(myRef, anotherRef);
  
  return <div ref={combinedRef}>Content</div>;
}

useEvent

Creates a stable callback function that always calls the latest version of the provided handler. Prevents unnecessary re-renders when passing callbacks to child components.

/**
 * Creates a stable callback function that always calls the latest handler
 * @param handler - The event handler function to stabilize (can be undefined)
 * @returns A stable callback function that never changes identity
 */
function useEvent<T extends Function>(handler: T | undefined): (...args: any[]) => any;

Usage Example:

import React, { useState } from "react";
import { useEvent } from "@dnd-kit/utilities";

function Counter() {
  const [count, setCount] = useState(0);
  
  // This callback will be stable across re-renders
  const handleIncrement = useEvent(() => {
    setCount(count + 1);
  });
  
  return (
    <div>
      <p>Count: {count}</p>
      <ExpensiveChild onIncrement={handleIncrement} />
    </div>
  );
}

useIsomorphicLayoutEffect

A hook that resolves to useEffect on the server and useLayoutEffect on the client. Prevents hydration mismatches in SSR applications.

/**
 * SSR-safe layout effect hook
 * Resolves to useLayoutEffect on client, useEffect on server
 */
const useIsomorphicLayoutEffect: typeof useLayoutEffect | typeof useEffect;

Usage Example:

import React, { useState } from "react";
import { useIsomorphicLayoutEffect } from "@dnd-kit/utilities";

function MeasuredComponent() {
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
  
  useIsomorphicLayoutEffect(() => {
    // Safe to use DOM measurements
    const element = document.getElementById("measured");
    if (element) {
      setDimensions({
        width: element.offsetWidth,
        height: element.offsetHeight,
      });
    }
  }, []);
  
  return <div id="measured">Width: {dimensions.width}px</div>;
}

useInterval

Provides a controlled way to manage intervals with automatic cleanup. Returns functions to set and clear intervals.

/**
 * Provides controlled interval management with automatic cleanup
 * @returns Tuple containing [set, clear] functions
 */
function useInterval(): readonly [
  (listener: Function, duration: number) => void,
  () => void
];

Usage Example:

import React, { useState } from "react";
import { useInterval } from "@dnd-kit/utilities";

function Timer() {
  const [count, setCount] = useState(0);
  const [set, clear] = useInterval();
  
  const startTimer = () => {
    set(() => setCount(c => c + 1), 1000);
  };
  
  const stopTimer = () => {
    clear();
  };
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={startTimer}>Start</button>
      <button onClick={stopTimer}>Stop</button>
    </div>
  );
}

useLatestValue

Stores a value in a ref and updates it when dependencies change. Useful for accessing the latest value in closures without stale closure issues.

/**
 * Stores a value in a ref and updates it when dependencies change
 * @param value - The value to store and keep updated
 * @param dependencies - Optional dependency list (defaults to [value])
 * @returns A ref object containing the latest value
 */
function useLatestValue<T>(
  value: T,
  dependencies?: DependencyList
): MutableRefObject<T>;

Usage Example:

import React, { useState, useCallback } from "react";
import { useLatestValue } from "@dnd-kit/utilities";

function AsyncComponent() {
  const [data, setData] = useState("initial");
  const latestData = useLatestValue(data);
  
  const fetchData = useCallback(async () => {
    // This async function can access the latest value
    // even if the component re-renders during the async operation
    const response = await fetch("/api/data");
    const result = await response.text();
    
    // latestData.current always has the most recent value
    console.log("Previous value:", latestData.current);
    setData(result);
  }, []); // No need to include data in dependencies
  
  return (
    <div>
      <p>Data: {data}</p>
      <button onClick={fetchData}>Fetch Data</button>
    </div>
  );
}

useLazyMemo

Similar to useMemo but provides access to the previous computed value in the callback. Useful for computing values that depend on their previous state.

/**
 * Memoization hook with access to previous computed value
 * @param callback - Function that receives the previous value and returns the new value
 * @param dependencies - Array of dependencies to watch for changes
 * @returns The memoized value returned by the callback
 */
function useLazyMemo<T>(
  callback: (prevValue: T | undefined) => T,
  dependencies: any[]
): T;

Usage Example:

import React, { useState } from "react";
import { useLazyMemo } from "@dnd-kit/utilities";

function AnimationComponent({ targetPosition }: { targetPosition: number }) {
  const animatedPosition = useLazyMemo(
    (prevPosition) => {
      // Gradually move toward target, starting from previous position
      const current = prevPosition ?? 0;
      const diff = targetPosition - current;
      return current + diff * 0.1; // 10% interpolation
    },
    [targetPosition]
  );
  
  return <div style={{ left: animatedPosition }}>Animated Element</div>;
}

useNodeRef

Manages an HTMLElement ref with optional change detection. Useful for tracking DOM node changes and performing side effects when elements are attached/detached.

/**
 * Manages an HTMLElement ref with optional change detection
 * @param onChange - Optional callback fired when the element changes
 * @returns Tuple containing [ref object, setter function]
 */
function useNodeRef(
  onChange?: (
    newElement: HTMLElement | null,
    previousElement: HTMLElement | null
  ) => void
): readonly [MutableRefObject<HTMLElement | null>, (element: HTMLElement | null) => void];

Usage Example:

import React, { useEffect } from "react";
import { useNodeRef } from "@dnd-kit/utilities";

function ObservedComponent() {
  const [nodeRef, setNodeRef] = useNodeRef((newElement, prevElement) => {
    if (newElement) {
      console.log("Element mounted:", newElement);
      // Set up observers, measurements, etc.
    }
    if (prevElement && !newElement) {
      console.log("Element unmounted:", prevElement);
      // Clean up observers
    }
  });
  
  // Use the ref
  return <div ref={nodeRef.current}>Observed content</div>;
}

usePrevious

Returns the previous value of a given variable. Useful for comparing current and previous values or implementing derived state based on value changes.

/**
 * Returns the previous value of a variable
 * @param value - The current value to track
 * @returns The previous value (undefined on first render)
 */
function usePrevious<T>(value: T): T | undefined;

Usage Example:

import React, { useState, useEffect } from "react";
import { usePrevious } from "@dnd-kit/utilities";

function ValueTracker({ value }: { value: number }) {
  const previousValue = usePrevious(value);
  
  useEffect(() => {
    if (previousValue !== undefined && previousValue !== value) {
      console.log(`Value changed from ${previousValue} to ${value}`);
    }
  }, [value, previousValue]);
  
  return (
    <div>
      <p>Current: {value}</p>
      <p>Previous: {previousValue ?? "None"}</p>
    </div>
  );
}

useUniqueId

Generates unique IDs with a given prefix or returns a provided value. Useful for accessibility attributes and form element IDs.

/**
 * Generates unique IDs with a given prefix
 * @param prefix - The prefix for the generated ID
 * @param value - Optional explicit value to use instead of generating an ID
 * @returns A unique ID string or the provided value
 */
function useUniqueId(prefix: string, value?: string): string;

Usage Example:

import React from "react";
import { useUniqueId } from "@dnd-kit/utilities";

function FormField({ label, value, onChange }: {
  label: string;
  value: string;
  onChange: (value: string) => void;
}) {
  const inputId = useUniqueId("form-field");
  
  return (
    <div>
      <label htmlFor={inputId}>{label}</label>
      <input
        id={inputId}
        value={value}
        onChange={(e) => onChange(e.target.value)}
      />
    </div>
  );
}