Repository: alibaba/hooks
Pull request #1054 (2021-07-21 06:10:57)

refactor: useSet


Patch:
diff --git a/packages/hooks/src/useSet/demo/demo1.tsx b/packages/hooks/src/useSet/demo/demo1.tsx
index f6ab4727..f7e78d75 100644
--- a/packages/hooks/src/useSet/demo/demo1.tsx
+++ b/packages/hooks/src/useSet/demo/demo1.tsx
@@ -10,7 +10,7 @@ import React from 'react';
 import { useSet } from 'ahooks';
 
 export default () => {
-  const [set, { add, has, remove, reset }] = useSet(['Hello']);
+  const [set, { add, remove, reset }] = useSet(['Hello']);
 
   return (
     <div>
@@ -20,7 +20,7 @@ export default () => {
       <button
         type="button"
         onClick={() => remove('Hello')}
-        disabled={!has('Hello')}
+        disabled={!set.has('Hello')}
         style={{ margin: '0 8px' }}
       >
         Remove Hello
diff --git a/packages/hooks/src/useSet/index.en-US.md b/packages/hooks/src/useSet/index.en-US.md
index 8b5419e0..66ffef81 100644
--- a/packages/hooks/src/useSet/index.en-US.md
+++ b/packages/hooks/src/useSet/index.en-US.md
@@ -10,6 +10,8 @@ group:
 
 # useSet
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that can manage the state of Set.
 
 ## Examples
@@ -25,7 +27,6 @@ const [
   set,
   {
     add,
-    has,
     remove,
     reset
   }
@@ -34,13 +35,12 @@ const [
 
 ### Result
 
-| Property | Description                          | Type                    |
-|----------|--------------------------------------|-------------------------|
-| set      | Set object                           | `Set`                   |
-| add      | add key                              | `(key: any) => void`    |
-| has      | Determine whether the element exists | `(key: any) => Boolean` |
-| remove   | remove key                           | `(key: any) => void`    |
-| reset    | reset to default                     | `() => void`            |
+| Property | Description      | Type                 |
+|----------|------------------|----------------------|
+| set      | Set object       | `Set`                |
+| add      | Add key          | `(key: any) => void` |
+| remove   | Remove key       | `(key: any) => void` |
+| reset    | Reset to default | `() => void`         |
 
 ### Params
 
diff --git a/packages/hooks/src/useSet/index.ts b/packages/hooks/src/useSet/index.ts
index 30977305..e7bd7cad 100644
--- a/packages/hooks/src/useSet/index.ts
+++ b/packages/hooks/src/useSet/index.ts
@@ -1,40 +1,45 @@
-/* eslint-disable max-len */
-import { useState, useMemo, useCallback } from 'react';
+import { useState } from 'react';
+import useMemoizedFn from '../useMemoizedFn';
 
 function useSet<K>(initialValue?: Iterable<K>) {
-  const initialSet = useMemo<Set<K>>(
-    () => (initialValue === undefined ? new Set() : new Set(initialValue)) as Set<K>,
-    [],
-  );
-  const [set, setSet] = useState(initialSet);
+  const getInitValue = () => {
+    return initialValue === undefined ? new Set<K>() : new Set(initialValue);
+  };
+
+  const [set, setSet] = useState<Set<K>>(() => getInitValue());
 
-  const stableActions = useMemo(
-    () => ({
-      add: (key: K) => {
-        setSet((prevSet) => {
-          const temp = new Set(prevSet);
-          temp.add(key);
-          return temp;
-        });
-      },
-      remove: (key: K) => {
-        setSet((prevSet) => {
-          const temp = new Set(prevSet);
-          temp.delete(key);
-          return temp;
-        });
-      },
-      reset: () => setSet(initialSet),
-    }),
-    [setSet, initialSet],
-  );
+  const add = (key: K) => {
+    if (set.has(key)) {
+      return;
+    }
+    setSet((prevSet) => {
+      const temp = new Set(prevSet);
+      temp.add(key);
+      return temp;
+    });
+  };
 
-  const utils = {
-    has: useCallback((key: K) => set.has(key), [set]),
-    ...stableActions,
+  const remove = (key: K) => {
+    if (!set.has(key)) {
+      return;
+    }
+    setSet((prevSet) => {
+      const temp = new Set(prevSet);
+      temp.delete(key);
+      return temp;
+    });
   };
 
-  return [set, utils] as const;
+  const reset = () => setSet(getInitValue());
+
+  return [
+    set,
+    {
+      add: useMemoizedFn(add),
+      remove: useMemoizedFn(remove),
+      reset: useMemoizedFn(reset),
+    },
+  ] as const;
 }
 
 export default useSet;
diff --git a/packages/hooks/src/useSet/index.zh-CN.md b/packages/hooks/src/useSet/index.zh-CN.md
index be225c43..ea17d4f4 100644
--- a/packages/hooks/src/useSet/index.zh-CN.md
+++ b/packages/hooks/src/useSet/index.zh-CN.md
@@ -10,6 +10,8 @@ group:
 
 # useSet
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 一个可以管理 Set 类型状态的 Hook。
 
 ## 代码演示
@@ -23,7 +25,6 @@ const [
   set,
   {
     add,
-    has,
     remove,
     reset
   }
@@ -36,7 +37,6 @@ const [
 |--------|------------------|-------------------------|
 | set    | Set 对象         | `Set`                   |
 | add    | 添加元素         | `(key: any) => void`    |
-| has    | 判断是否存在元素 | `(key: any) => Boolean` |
 | remove | 移除元素         | `(key: any) => void`    |
 | reset  | 重置为默认值     | `() => void`            |
 


Test patch:
diff --git a/packages/hooks/src/useSet/__tests__/index.test.ts b/packages/hooks/src/useSet/__tests__/index.test.ts
index 4203617d..fd13a876 100644
--- a/packages/hooks/src/useSet/__tests__/index.test.ts
+++ b/packages/hooks/src/useSet/__tests__/index.test.ts
@@ -9,7 +9,6 @@ it('should init set and utils', () => {
 
   expect(set).toEqual(new Set([1, 2]));
   expect(utils).toStrictEqual({
-    has: expect.any(Function),
     add: expect.any(Function),
     remove: expect.any(Function),
     reset: expect.any(Function),
@@ -24,11 +23,11 @@ it('should init empty set if no initial set provided', () => {
 
 it('should have an initially provided key', () => {
   const { result } = setUp(['a']);
-  const [, utils] = result.current;
+  const [set, utils] = result.current;
 
   let value;
   act(() => {
-    value = utils.has('a');
+    value = set.has('a');
   });
 
   expect(value).toBe(true);
@@ -43,7 +42,7 @@ it('should have an added key', () => {
 
   let value;
   act(() => {
-    value = result.current[1].has('newKey');
+    value = result.current[0].has('newKey');
   });
 
   expect(value).toBe(true);
@@ -51,11 +50,11 @@ it('should have an added key', () => {
 
 it('should get false for non-existing key', () => {
   const { result } = setUp(['a']);
-  const [, utils] = result.current;
+  const [set] = result.current;
 
   let value;
   act(() => {
-    value = utils.has('nonExisting');
+    value = set.has('nonExisting');
   });
 
   expect(value).toBe(false);