useSet

A hook that returns a reactive Set with add, delete, and clear operations that automatically trigger re-renders.

Installation

import { useSet } from 'data-strcture-react-hooks';

Basic Usage

function MyComponent() {
  const set = useSet(['item1', 'item2']);

  return (
    <div>
      <p>Size: {set.size}</p>
      <button onClick={() => set.add('item3')}>Add Item</button>
      <button onClick={() => set.delete('item1')}>Remove Item</button>
    </div>
  );
}

API Reference

Parameters

  • defaultValue (T[]): The initial set values

Returns

A reactive Set with add, delete, and clear operations that automatically trigger re-renders when mutated.

Supported Methods

The returned Set supports the following mutating methods:

  • add(value) - Adds a value to the set
  • delete(value) - Removes a value from the set
  • clear() - Removes all values from the set

Non-Mutating Methods

The following methods work as expected but don't trigger re-renders:

  • has(value) - Checks if a value exists in the set
  • values() - Returns an iterator of values
  • forEach(callback) - Iterates over all values

Live Example

Try out the useSet hook with this interactive example:

Current Set:

apple, banana, orange

Size: 3

Has 'apple': Yes

Has 'grape': No

All values: apple, banana, orange

Examples

Basic Set Operations

const set = useSet(['apple', 'banana']);

// Add values
set.add('orange');              // Set(3) { 'apple', 'banana', 'orange' }
set.add('grape');               // Set(4) { 'apple', 'banana', 'orange', 'grape' }

// Remove values
set.delete('banana');           // Set(3) { 'apple', 'orange', 'grape' }

// Clear all
set.clear();                    // Set(0) {}

Unique Tags Example

function TagSelector() {
  const selectedTags = useSet([]);
  const [inputValue, setInputValue] = useState('');

  const addTag = () => {
    if (inputValue.trim() && !selectedTags.has(inputValue)) {
      selectedTags.add(inputValue);
      setInputValue('');
    }
  };

  const removeTag = (tag) => {
    selectedTags.delete(tag);
  };

  return (
    <div>
      <div>
        <input
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          placeholder="Enter a tag"
        />
        <button onClick={addTag}>Add Tag</button>
      </div>

      <div>
        {Array.from(selectedTags).map(tag => (
          <span key={tag} className="tag">
            {tag}
            <button onClick={() => removeTag(tag)}>×</button>
          </span>
        ))}
      </div>
    </div>
  );
}

Permission System Example

function PermissionManager() {
  const permissions = useSet(['read', 'write']);

  const togglePermission = (permission) => {
    if (permissions.has(permission)) {
      permissions.delete(permission);
    } else {
      permissions.add(permission);
    }
  };

  const hasPermission = (permission) => {
    return permissions.has(permission);
  };

  return (
    <div>
      <h3>User Permissions</h3>

      <div>
        <label>
          <input
            type="checkbox"
            checked={hasPermission('read')}
            onChange={() => togglePermission('read')}
          />
          Read Access
        </label>
      </div>

      <div>
        <label>
          <input
            type="checkbox"
            checked={hasPermission('write')}
            onChange={() => togglePermission('write')}
          />
          Write Access
        </label>
      </div>

      <div>
        <label>
          <input
            type="checkbox"
            checked={hasPermission('admin')}
            onChange={() => togglePermission('admin')}
          />
          Admin Access
        </label>
      </div>

      <p>Active permissions: {Array.from(permissions).join(', ')}</p>
    </div>
  );
}

How It Works

The useSet hook uses JavaScript's Proxy API to intercept method calls on the Set. When a mutating method (add, delete, clear) is called, it triggers a re-render of the component by updating an internal state variable. This ensures that your UI stays in sync with the Set's state.

TypeScript Support

The hook is fully typed and supports generic types:

const stringSet = useSet<string>(['a', 'b', 'c']);
const numberSet = useSet<number>([1, 2, 3]);
const mixedSet = useSet<any>([1, 'string', { id: 1 }]);