Skip to main content
useRefMap
@coinbase/cds-common@8.13.6
Manages a collection of refs using a key-value map structure, allowing dynamic registration and retrieval of refs by their unique identifiers. Commonly used in components that need to track multiple DOM elements, such as tabs, tours, or complex navigation systems.
Import
import { useRefMap } from '@coinbase/cds-common/hooks/useRefMap'
SourceView source code

Basic usage

Loading...
Live Code
function Example() {
  const { registerRef, getRef } = useRefMap<HTMLDivElement>();
  const toast = useToast();

  const handleClick = () => {
    // Get the element by its ID and log its dimensions
    const element = getRef('box1');
    if (element) {
      toast.show(`Box dimensions: ${element.offsetWidth}x${element.offsetHeight}`);
    }
  };

  return (
    <VStack gap={2}>
      <Box
        ref={(el) => el && registerRef('box1', el)}
        padding={3}
        background="bgAlternate"
        borderRadius={300}
      >
        <TextBody>This box is registered with ID 'box1'</TextBody>
      </Box>
      <Button onClick={handleClick}>Get Box Dimensions</Button>
    </VStack>
  );
}

With Multiple Elements

Loading...
Live Code
function Example() {
  const { registerRef, getRef } = useRefMap<HTMLDivElement>();
  const [activeId, setActiveId] = useState<string | null>(null);

  const highlightElement = (id: string) => {
    // Reset previous highlight
    if (activeId) {
      const prevElement = getRef(activeId);
      if (prevElement) {
        prevElement.style.outline = 'none';
      }
    }

    // Highlight new element
    const element = getRef(id);
    if (element) {
      element.style.outline = '2px solid var(--color-fgPrimary)';
      setActiveId(id);
    }
  };

  return (
    <VStack gap={3}>
      <HStack gap={2}>
        <Button onClick={() => highlightElement('box1')}>Highlight Box 1</Button>
        <Button onClick={() => highlightElement('box2')}>Highlight Box 2</Button>
        <Button onClick={() => highlightElement('box3')}>Highlight Box 3</Button>
      </HStack>

      <VStack gap={2}>
        <Box
          ref={(el) => el && registerRef('box1', el)}
          padding={3}
          background="bgAlternate"
          borderRadius={300}
        >
          <TextBody>Box 1</TextBody>
        </Box>

        <Box
          ref={(el) => el && registerRef('box2', el)}
          padding={3}
          background="bgAlternate"
          borderRadius={300}
        >
          <TextBody>Box 2</TextBody>
        </Box>

        <Box
          ref={(el) => el && registerRef('box3', el)}
          padding={3}
          background="bgAlternate"
          borderRadius={300}
        >
          <TextBody>Box 3</TextBody>
        </Box>
      </VStack>
    </VStack>
  );
}

With Initial Refs

Loading...
Live Code
function Example() {
  // Create initial refs map
  const box1Ref = useRef<HTMLDivElement>(null);
  const box2Ref = useRef<HTMLDivElement>(null);

  const initialRefs = {
    box1: box1Ref.current,
    box2: box2Ref.current,
  };

  const { refs, registerRef } = useRefMap<HTMLDivElement>({
    initialRefMap: initialRefs,
  });

  const logRefs = () => {
    console.log('Current refs:', refs);
  };

  return (
    <VStack gap={2}>
      <Box
        ref={(el) => el && registerRef('box1', el)}
        padding={3}
        background="bgAlternate"
        borderRadius={300}
      >
        <TextBody>Box 1</TextBody>
      </Box>

      <Box
        ref={(el) => el && registerRef('box2', el)}
        padding={3}
        background="bgAlternate"
        borderRadius={300}
      >
        <TextBody>Box 2</TextBody>
      </Box>

      <Button onClick={logRefs}>Log Refs</Button>
    </VStack>
  );
}

Is this page useful?

Coinbase Design is an open-source, adaptable system of guidelines, components, and tools that aid the best practices of user interface design for crypto products.