react-use/src/useSet.ts
xobotyi b6993a6f95
feat(prettier): make prettier a part of eslint.
Also reduce max line width to 100. And remove `lint:types` step for
commit sequence, it bothers when committing incomplete (wip) changes.
2021-02-01 18:58:55 +03:00

40 lines
1.1 KiB
TypeScript

import { useCallback, useMemo, useState } from 'react';
export interface StableActions<K> {
add: (key: K) => void;
remove: (key: K) => void;
toggle: (key: K) => void;
reset: () => void;
}
export interface Actions<K> extends StableActions<K> {
has: (key: K) => boolean;
}
const useSet = <K>(initialSet = new Set<K>()): [Set<K>, Actions<K>] => {
const [set, setSet] = useState(initialSet);
const stableActions = useMemo<StableActions<K>>(() => {
const add = (item: K) => setSet((prevSet) => new Set([...Array.from(prevSet), item]));
const remove = (item: K) =>
setSet((prevSet) => new Set(Array.from(prevSet).filter((i) => i !== item)));
const toggle = (item: K) =>
setSet((prevSet) =>
prevSet.has(item)
? new Set(Array.from(prevSet).filter((i) => i !== item))
: new Set([...Array.from(prevSet), item])
);
return { add, remove, toggle, reset: () => setSet(initialSet) };
}, [setSet]);
const utils = {
has: useCallback((item) => set.has(item), [set]),
...stableActions,
} as Actions<K>;
return [set, utils];
};
export default useSet;