Merge pull request #827 from stefanbugge/pr/808-fix-useset-outdated-closure

fix(useSet): "has" method in useSet updated to reference latest set object
This commit is contained in:
Vadim Dalecky 2019-12-10 02:45:55 -08:00 committed by GitHub
commit 208b869f97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 7 deletions

View File

@ -1,18 +1,20 @@
import { useState, useMemo } from 'react';
import { useState, useMemo, useCallback } from 'react';
export interface Actions<K> {
has: (key: K) => boolean;
export interface StableActions<K> {
add: (key: K) => void;
remove: (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 utils = useMemo<Actions<K>>(
const stableActions = useMemo<StableActions<K>>(
() => ({
has: item => set.has(item),
add: item => setSet(prevSet => new Set([...Array.from(prevSet), item])),
remove: item => setSet(prevSet => new Set(Array.from(prevSet).filter(i => i !== item))),
reset: () => setSet(initialSet),
@ -20,6 +22,11 @@ const useSet = <K>(initialSet = new Set<K>()): [Set<K>, Actions<K>] => {
[setSet]
);
const utils = {
has: useCallback(item => set.has(item), [set]),
...stableActions,
} as Actions<K>;
return [set, utils];
};

View File

@ -34,6 +34,21 @@ it('should have an initially provided key', () => {
expect(value).toBe(true);
});
it('should have an added key', () => {
const { result } = setUp(new Set());
act(() => {
result.current[1].add('newKey');
});
let value;
act(() => {
value = result.current[1].has('newKey');
});
expect(value).toBe(true);
});
it('should get false for non-existing key', () => {
const { result } = setUp(new Set(['a']));
const [, utils] = result.current;
@ -110,12 +125,13 @@ it('should reset to initial set provided', () => {
it('should memoized its utils methods', () => {
const { result } = setUp(new Set(['a', 'b']));
const [, utils] = result.current;
const { add } = utils;
const { add, remove, reset } = utils;
act(() => {
add('foo');
});
expect(result.current[1]).toBe(utils);
expect(result.current[1].add).toBe(add);
expect(result.current[1].remove).toBe(remove);
expect(result.current[1].reset).toBe(reset);
});