Skip to content

Instantly share code, notes, and snippets.

@srflp
Created October 31, 2024 17:18
Show Gist options
  • Save srflp/c4b21b1d8cb46bdb3db43fd909fa39d7 to your computer and use it in GitHub Desktop.
Save srflp/c4b21b1d8cb46bdb3db43fd909fa39d7 to your computer and use it in GitHub Desktop.
import {
useCallback,
useState,
} from "react"
/**
* Allows to use a Set as a state more conveniently.
*/
export function useSet<T>(initialValues?: Iterable<T> | null) {
const [set, setSet] = useState<Set<T>>(new Set(initialValues))
const add = useCallback((item: T) => {
setSet((prevSet) => new Set(prevSet).add(item))
}, [])
const remove = useCallback((item: T) => {
setSet((prevSet) => {
const newSet = new Set(prevSet)
newSet.delete(item)
return newSet
})
}, [])
const has = useCallback((item: T) => set.has(item), [set])
const clear = useCallback(() => setSet(new Set()), [])
const toggle = useCallback((item: T) => {
setSet((prevSet) => {
const newSet = new Set(prevSet)
if (newSet.has(item)) {
newSet.delete(item)
} else {
newSet.add(item)
}
return newSet
})
}, [])
const forEach = useCallback(
(callback: (item: T) => void) => {
set.forEach(callback)
},
[set]
)
const map = useCallback(
<U>(callback: (item: T) => U): U[] => {
const result: U[] = []
set.forEach((item) => result.push(callback(item)))
return result
},
[set]
)
const toArray = useCallback(() => Array.from(set), [set])
const size = set.size
const isEmpty = size === 0
return {
set,
add,
remove,
has,
clear,
toggle,
toArray,
forEach,
map,
size,
isEmpty
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment