Created
September 21, 2024 09:10
-
-
Save chaance/a5fa6df5faee5f4b61386b65f5809e3d to your computer and use it in GitHub Desktop.
useMap / useSet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react'; | |
export function useMap<K = unknown, V = unknown>( | |
initialEntries?: readonly (readonly [K, V])[] | null, | |
): IMap<K, V> { | |
const [map, setMap] = React.useState(() => new Map(initialEntries)); | |
return { | |
raw: map, | |
clear: React.useCallback(() => { | |
setMap((map) => { | |
return map.size === 0 ? map : new Map(); | |
}); | |
}, []), | |
delete: React.useCallback((key: K) => { | |
setMap((map) => { | |
if (!map.has(key)) { | |
return map; | |
} | |
const copy = new Map(map); | |
copy.delete(key); | |
return copy; | |
}); | |
}, []), | |
get: React.useCallback((key: K) => map.get(key), [map]), | |
has: React.useCallback((key: K) => map.has(key), [map]), | |
set: React.useCallback( | |
(key: K, action: V | ((prevState: V | undefined) => V)) => { | |
setMap((map) => { | |
const current = map.get(key); | |
const next = isFunction(action) ? action(current) : action; | |
if (current === next) { | |
return map; | |
} | |
return new Map(map.set(key, next)); | |
}); | |
}, | |
[], | |
), | |
size: map.size, | |
map: React.useCallback( | |
(callbackFn) => { | |
const result: ReturnType<typeof callbackFn>[] = []; | |
for (const entry of map) { | |
result.push(callbackFn(entry, result.length, map)); | |
} | |
return result; | |
}, | |
[map], | |
), | |
}; | |
} | |
interface IMap<K, V> { | |
raw: Map<K, V>; | |
clear(): void; | |
delete(key: K): void; | |
get(key: K): V | undefined; | |
has(key: K): boolean; | |
set(key: K, action: V | ((prevState: V | undefined) => V)): void; | |
map<U>(callbackFn: (entry: [K, V], index: number, map: Map<K, V>) => U): U[]; | |
readonly size: number; | |
} | |
function isFunction(value: unknown): value is (...args: any[]) => any { | |
return typeof value === 'function'; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react'; | |
export function useSet<T = unknown>( | |
initialValues: readonly T[] | null, | |
): ISet<T> { | |
const [set, setSet] = React.useState(() => new Set(initialValues)); | |
return { | |
raw: set, | |
add: React.useCallback((value: T) => { | |
setSet((set) => { | |
if (set.has(value)) { | |
return set; | |
} | |
const copy = new Set(set); | |
copy.add(value); | |
return copy; | |
}); | |
}, []), | |
clear: React.useCallback(() => { | |
setSet((set) => { | |
return set.size === 0 ? set : new Set(); | |
}); | |
}, []), | |
delete: React.useCallback( | |
(value: T) => | |
setSet((set) => { | |
if (!set.has(value)) { | |
return set; | |
} | |
const copy = new Set(set); | |
copy.delete(value); | |
return copy; | |
}), | |
[], | |
), | |
has: React.useCallback((value: T) => set.has(value), [set]), | |
map: React.useCallback( | |
(callbackFn) => { | |
const result: ReturnType<typeof callbackFn>[] = []; | |
for (const value of set) { | |
result.push(callbackFn(value, result.length, set)); | |
} | |
return result; | |
}, | |
[set], | |
), | |
size: set.size, | |
}; | |
} | |
interface ISet<T> { | |
raw: Set<T>; | |
add(value: T): void; | |
clear(): void; | |
delete(value: T): void; | |
has(value: T): boolean; | |
map<U>(callbackFn: (value: T, index: number, set: Set<T>) => U): U[]; | |
readonly size: number; | |
} | |
function isFunction(value: unknown): value is (...args: any[]) => any { | |
return typeof value === 'function'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment