useHooks.iov4.1.2
DocsBlogGitHub
Hooks
No hooks found in any category.

useSymbol

utility

Installation

npx usehooks-cli@latest add use-symbol

Description

A React hook that provides utilities for creating and managing JavaScript Symbols. Symbols are primitive values that are guaranteed to be unique and are often used as unique property keys that won't collide with other code. This hook offers symbol creation, global registry management, and access to well-known symbols.

Return Type

UseSymbolReturn
PropertyTypeDescription
createSymbol(description?: string) => symbolCreates a new unique symbol with optional description
getGlobalSymbol(key: string) => symbolGets or creates a symbol from the global symbol registry
getSymbolKey(symbol: symbol) => string | undefinedGets the key for a symbol in the global registry
isSymbol(value: any) => value is symbolType guard to check if a value is a symbol
getDescription(symbol: symbol) => string | undefinedGets the description of a symbol
wellKnownSymbolsobjectObject containing all well-known symbols (iterator, hasInstance, etc.)
symbolssymbol[]Array of symbols created or managed by this hook
addSymbol(symbol: symbol) => voidAdds an existing symbol to the managed collection
removeSymbol(symbol: symbol) => voidRemoves a symbol from the managed collection
clearSymbols() => voidClears all symbols from the managed collection

Examples

Creating Unique Property Keys

Use symbols as unique property keys that won't collide

1const { createSymbol } = useSymbol(); 2 3const privateKey = createSymbol('private'); 4const obj = { 5 publicProp: 'visible', 6 [privateKey]: 'hidden' 7}; 8 9// privateKey is unique and won't conflict with other properties

Global Symbol Registry

Share symbols across different parts of your application

1const { getGlobalSymbol, getSymbolKey } = useSymbol(); 2 3const sharedSymbol = getGlobalSymbol('app.config'); 4const key = getSymbolKey(sharedSymbol); // 'app.config' 5 6// Same symbol can be retrieved elsewhere with getGlobalSymbol('app.config')

Well-Known Symbols

Access built-in JavaScript symbols for custom behavior

1const { wellKnownSymbols } = useSymbol(); 2 3const customIterable = { 4 [wellKnownSymbols.iterator]: function* () { 5 yield 1; 6 yield 2; 7 yield 3; 8 } 9}; 10 11// Now customIterable can be used with for...of loops

Symbol Management

Track and manage symbols in your component

1const { symbols, createSymbol, removeSymbol, clearSymbols } = useSymbol(); 2 3const handleCreateKey = () => { 4 const newKey = createSymbol('dynamic-key'); 5 console.log(`Created symbol, total: ${symbols.length}`); 6}; 7 8const handleClear = () => { 9 clearSymbols(); 10 console.log('All symbols cleared'); 11};

Type Checking and Utilities

Utility functions for working with symbols

1const { isSymbol, getDescription, createSymbol } = useSymbol(); 2 3const mySymbol = createSymbol('test symbol'); 4 5if (isSymbol(mySymbol)) { 6 const desc = getDescription(mySymbol); // 'test symbol' 7 console.log(`Symbol description: ${desc}`); 8}

Dependencies

react

Notes

  • Symbols created with createSymbol() are guaranteed to be unique
  • Global symbols created with getGlobalSymbol() can be shared across the application
  • Well-known symbols enable customization of built-in JavaScript operations
  • The hook maintains a collection of symbols for easy management and cleanup
  • Symbols are garbage collectable and can be used as WeakMap keys
  • Each Symbol() call creates a completely unique value, even with the same description

Implementation

1"use client"; 2 3import { useState, useCallback, useMemo, useRef } from "react"; 4 5interface UseSymbolReturn { 6 // Create new unique symbols 7 createSymbol: (description?: string) => symbol; 8 9 // Global symbol registry operations 10 getGlobalSymbol: (key: string) => symbol; 11 getSymbolKey: (symbol: symbol) => string | undefined; 12 13 // Symbol utilities 14 isSymbol: (value: any) => value is symbol; 15 getDescription: (symbol: symbol) => string | undefined; 16 17 // Well-known symbols 18 wellKnownSymbols: { 19 iterator: symbol; 20 asyncIterator: symbol; 21 hasInstance: symbol; 22 isConcatSpreadable: symbol; 23 species: symbol; 24 toPrimitive: symbol; 25 toStringTag: symbol; 26 unscopables: symbol; 27 match: symbol; 28 matchAll: symbol; 29 replace: symbol; 30 search: symbol; 31 split: symbol; 32 }; 33 34 // Symbol collection management 35 symbols: symbol[]; 36 addSymbol: (symbol: symbol) => void; 37 removeSymbol: (symbol: symbol) => void; 38 clearSymbols: () => void; 39} 40 41export function useSymbol(): UseSymbolReturn { 42 const [symbols, setSymbols] = useState<symbol[]>([]); 43 const symbolsRef = useRef<Set<symbol>>(new Set()); 44 45 const createSymbol = useCallback((description?: string): symbol => { 46 const newSymbol = Symbol(description); 47 setSymbols((prev) => [...prev, newSymbol]); 48 symbolsRef.current.add(newSymbol); 49 return newSymbol; 50 }, []); 51 52 const getGlobalSymbol = useCallback((key: string): symbol => { 53 return Symbol.for(key); 54 }, []); 55 56 const getSymbolKey = useCallback((symbol: symbol): string | undefined => { 57 return Symbol.keyFor(symbol); 58 }, []); 59 60 const isSymbol = useCallback((value: any): value is symbol => { 61 return typeof value === "symbol"; 62 }, []); 63 64 const getDescription = useCallback((symbol: symbol): string | undefined => { 65 return symbol.description; 66 }, []); 67 68 const addSymbol = useCallback((symbol: symbol) => { 69 if (!symbolsRef.current.has(symbol)) { 70 setSymbols((prev) => [...prev, symbol]); 71 symbolsRef.current.add(symbol); 72 } 73 }, []); 74 75 const removeSymbol = useCallback((symbol: symbol) => { 76 if (symbolsRef.current.has(symbol)) { 77 setSymbols((prev) => prev.filter((s) => s !== symbol)); 78 symbolsRef.current.delete(symbol); 79 } 80 }, []); 81 82 const clearSymbols = useCallback(() => { 83 setSymbols([]); 84 symbolsRef.current.clear(); 85 }, []); 86 87 const wellKnownSymbols = useMemo( 88 () => ({ 89 iterator: Symbol.iterator, 90 asyncIterator: Symbol.asyncIterator, 91 hasInstance: Symbol.hasInstance, 92 isConcatSpreadable: Symbol.isConcatSpreadable, 93 species: Symbol.species, 94 toPrimitive: Symbol.toPrimitive, 95 toStringTag: Symbol.toStringTag, 96 unscopables: Symbol.unscopables, 97 match: Symbol.match, 98 matchAll: Symbol.matchAll, 99 replace: Symbol.replace, 100 search: Symbol.search, 101 split: Symbol.split, 102 }), 103 [] 104 ); 105 106 return { 107 createSymbol, 108 getGlobalSymbol, 109 getSymbolKey, 110 isSymbol, 111 getDescription, 112 wellKnownSymbols, 113 symbols, 114 addSymbol, 115 removeSymbol, 116 clearSymbols, 117 }; 118} 119