Repository: alibaba/hooks
Pull request #1048 (2021-07-20 08:20:19)

refactor: useToggle & useBoolean


Patch:
diff --git a/packages/hooks/src/useBoolean/demo/demo1.tsx b/packages/hooks/src/useBoolean/demo/demo1.tsx
index becc39a8..a252f96b 100644
--- a/packages/hooks/src/useBoolean/demo/demo1.tsx
+++ b/packages/hooks/src/useBoolean/demo/demo1.tsx
@@ -1,9 +1,9 @@
 /**
  * title: Default usage
- * desc: Default as a switch function, or accept a parameter to change state.
+ * desc: Toggle Boolean, can set default value.
  *
  * title.zh-CN: 基础用法
- * desc.zh-CN: 默认切换布尔值状态，也可以接收一个参数作为新的值。
+ * desc.zh-CN: 切换 Boolean，可以接收一个参数作为默认值。
  */
 
 import React from 'react';
@@ -16,7 +16,7 @@ export default () => {
     <div>
       <p>Effects：{JSON.stringify(state)}</p>
       <p>
-        <button type="button" onClick={() => toggle()}>
+        <button type="button" onClick={toggle}>
           Toggle
         </button>
         <button type="button" onClick={setFalse} style={{ margin: '0 16px' }}>
diff --git a/packages/hooks/src/useBoolean/index.en-US.md b/packages/hooks/src/useBoolean/index.en-US.md
index 2f43ad3d..e5c01215 100644
--- a/packages/hooks/src/useBoolean/index.en-US.md
+++ b/packages/hooks/src/useBoolean/index.en-US.md
@@ -6,11 +6,12 @@ nav:
 group:
   title: State
   path: /state
-  order: 11
 ---
 
 # useBoolean
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that elegantly manages boolean values.
 
 ## Examples
@@ -22,7 +23,7 @@ A hook that elegantly manages boolean values.
 ## API
 
 ```typescript
-const [ state, { toggle, setTrue, setFalse }] = useBoolean(
+const [ state, { toggle, set, setTrue, setFalse }] = useBoolean(
   defaultValue?: boolean,
 );
 ```
@@ -37,12 +38,13 @@ const [ state, { toggle, setTrue, setFalse }] = useBoolean(
 
 | Property | Description   | Type      |
 |----------|---------------|-----------|
-| state    | State value   | `boolean` |
+| state    | Current State | `boolean` |
 | actions  | Operation set | `Actions` |
 
 ### Actions
-| Property | Description                                        | Type                        |
-|----------|----------------------------------------------------|-----------------------------|
-| toggle   | Trigger state change, accept an optional parameter | `(value?: boolean) => void` |
-| setTrue  | Set state value true                               | `() => void`                |
-| setFalse | Set state value false                              | `() => void`                |
+| Property | Description        | Type                       |
+|----------|--------------------|----------------------------|
+| toggle   | Toggle state       | `() => void`               |
+| set      | Set state          | `(value: boolean) => void` |
+| setTrue  | Set state to true  | `() => void`               |
+| setFalse | Set state to false | `() => void`               |
diff --git a/packages/hooks/src/useBoolean/index.ts b/packages/hooks/src/useBoolean/index.ts
index fcd4a115..94d2f901 100644
--- a/packages/hooks/src/useBoolean/index.ts
+++ b/packages/hooks/src/useBoolean/index.ts
@@ -4,17 +4,18 @@ import useToggle from '../useToggle';
 export interface Actions {
   setTrue: () => void;
   setFalse: () => void;
-  toggle: (value?: boolean | undefined) => void;
+  set: (value: boolean) => void;
+  toggle: () => void;
 }
 
 export default function useBoolean(defaultValue = false): [boolean, Actions] {
-  const [state, { toggle }] = useToggle(defaultValue);
+  const [state, { toggle, set }] = useToggle(defaultValue);
 
   const actions: Actions = useMemo(() => {
-    const setTrue = () => toggle(true);
-    const setFalse = () => toggle(false);
-    return { toggle, setTrue, setFalse };
-  }, [toggle]);
+    const setTrue = () => set(true);
+    const setFalse = () => set(false);
+    return { toggle, set, setTrue, setFalse };
+  }, []);
 
   return [state, actions];
 }
diff --git a/packages/hooks/src/useBoolean/index.zh-CN.md b/packages/hooks/src/useBoolean/index.zh-CN.md
index e5e1f077..0a0a2c68 100644
--- a/packages/hooks/src/useBoolean/index.zh-CN.md
+++ b/packages/hooks/src/useBoolean/index.zh-CN.md
@@ -6,11 +6,12 @@ nav:
 group:
   title: State
   path: /state
-  order: 11
 ---
 
 # useBoolean
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 优雅的管理 boolean 值的 Hook。
 
 ## 代码演示
@@ -22,7 +23,7 @@ group:
 ## API
 
 ```typescript
-const [ state, { toggle, setTrue, setFalse }] = useBoolean(
+const [ state, { toggle, set, setTrue, setFalse }] = useBoolean(
   defaultValue?: boolean,
 );
 ```
@@ -43,8 +44,9 @@ const [ state, { toggle, setTrue, setFalse }] = useBoolean(
 
 ### Actions
 
-| 参数     | 说明                                              | 类型                        |
-|----------|---------------------------------------------------|-----------------------------|
-| toggle   | 触发状态更改的函数,可以接受一个可选参数修改状态值 | `(value?: boolean) => void` |
-| setTrue  | 设置状态值为 true                                 | `() => void`                |
-| setFalse | 设置状态值为 false                                | `() => void`                |
+| 参数     | 说明         | 类型                       |
+|----------|--------------|----------------------------|
+| toggle   | 切换 state   | `() => void`               |
+| set      | 设置 state   | `(value: boolean) => void` |
+| setTrue  | 设置为 true  | `() => void`               |
+| setFalse | 设置为 false | `() => void`               |
diff --git a/packages/hooks/src/useMount/demo/demo1.tsx b/packages/hooks/src/useMount/demo/demo1.tsx
index 7fcb067e..6ce30e2c 100644
--- a/packages/hooks/src/useMount/demo/demo1.tsx
+++ b/packages/hooks/src/useMount/demo/demo1.tsx
@@ -6,9 +6,9 @@
  * desc.zh-CN: 在组件首次渲染时，执行方法。
  */
 
-import React from 'react';
+import { useMount, useToggle } from 'ahooks';
 import { message } from 'antd';
-import { useToggle, useMount } from 'ahooks';
+import React from 'react';
 
 const MyComponent = () => {
   useMount(() => {
@@ -23,7 +23,7 @@ export default () => {
 
   return (
     <>
-      <button type="button" onClick={() => toggle()}>
+      <button type="button" onClick={toggle}>
         {state ? 'unmount' : 'mount'}
       </button>
       {state && <MyComponent />}
diff --git a/packages/hooks/src/useToggle/demo/demo1.tsx b/packages/hooks/src/useToggle/demo/demo1.tsx
index 9a34779b..9458470b 100644
--- a/packages/hooks/src/useToggle/demo/demo1.tsx
+++ b/packages/hooks/src/useToggle/demo/demo1.tsx
@@ -1,6 +1,6 @@
 /**
  * title: Default usage
- * desc: use boolean value as default，use it as same as useBoolean.
+ * desc: Default value is boolean，use it as same as useBoolean.
  *
  * title.zh-CN: 基础用法
  * desc.zh-CN: 默认为 boolean 切换，基础用法与 useBoolean 一致。
@@ -10,19 +10,19 @@ import React from 'react';
 import { useToggle } from 'ahooks';
 
 export default () => {
-  const [state, { toggle }] = useToggle();
+  const [state, { toggle, setLeft, setRight }] = useToggle();
 
   return (
     <div>
       <p>Effects：{`${state}`}</p>
       <p>
-        <button type="button" onClick={() => toggle()}>
+        <button type="button" onClick={toggle}>
           Toggle
         </button>
-        <button type="button" onClick={() => toggle(false)} style={{ margin: '0 8px' }}>
+        <button type="button" onClick={setLeft} style={{ margin: '0 8px' }}>
           Toggle False
         </button>
-        <button type="button" onClick={() => toggle(true)}>
+        <button type="button" onClick={setRight}>
           Toggle True
         </button>
       </p>
diff --git a/packages/hooks/src/useToggle/demo/demo2.tsx b/packages/hooks/src/useToggle/demo/demo2.tsx
index 2cde99dd..f7fbbb8d 100644
--- a/packages/hooks/src/useToggle/demo/demo2.tsx
+++ b/packages/hooks/src/useToggle/demo/demo2.tsx
@@ -10,7 +10,7 @@ import React from 'react';
 import { useToggle } from 'ahooks';
 
 export default () => {
-  const [state, { toggle, setLeft, setRight }] = useToggle('Hello', 'World');
+  const [state, { toggle, set, setLeft, setRight }] = useToggle('Hello', 'World');
 
   return (
     <div>
@@ -19,17 +19,17 @@ export default () => {
         <button type="button" onClick={() => toggle()}>
           Toggle
         </button>
-        <button type="button" onClick={() => toggle('Hello')} style={{ margin: '0 8px' }}>
-          Toggle Hello
+        <button type="button" onClick={() => set('Hello')} style={{ margin: '0 8px' }}>
+          Set Hello
         </button>
-        <button type="button" onClick={() => toggle('World')}>
-          Toggle World
+        <button type="button" onClick={() => set('World')}>
+          Set World
         </button>
         <button type="button" onClick={setLeft} style={{ margin: '0 8px' }}>
-          Set Hello
+          Set Left
         </button>
         <button type="button" onClick={setRight}>
-          Set World
+          Set Right
         </button>
       </p>
     </div>
diff --git a/packages/hooks/src/useToggle/index.en-US.md b/packages/hooks/src/useToggle/index.en-US.md
index 32ee0b10..b60e470a 100644
--- a/packages/hooks/src/useToggle/index.en-US.md
+++ b/packages/hooks/src/useToggle/index.en-US.md
@@ -10,6 +10,8 @@ group:
 
 # useToggle
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that switch value between two states.
 
 ## Examples
@@ -25,34 +27,35 @@ A hook that switch value between two states.
 ## API
 
 ```typescript
-const [state, { toggle, setLeft, setRight }] = useToggle(
+const [state, { toggle, set, setLeft, setRight }] = useToggle(
   defaultValue?: boolean,
 );
 
-const [state, { toggle, setLeft, setRight }] = useToggle(
-  defaultValue: any = false,
-  reverseValue?: any,
+const [state, { toggle, set, setLeft, setRight }] = useToggle(
+  defaultValue: any,
+  reverseValue: any,
 );
 ```
 
 ### Params
 
-| Property     | Description                  | Type                                     | Default |
-| ------------ | ---------------------------- | ---------------------------------------- | ------- |
-| defaultValue | Optional，set a default value | `number` \| `string` \| `boolean` \| `undefined` | false   |
-| reverseValue | Optional，set a reverse value | `number` \| `string` \| `boolean` \| `undefined` | -       |
+| Property     | Description                   | Type  | Default |
+|--------------|-------------------------------|-------|---------|
+| defaultValue | Optional，set a default value | `any` | false   |
+| reverseValue | Optional，set a reverse value | `any` | -       |
 
 ### Result
 
-| Property | Description   | Type    |
-| -------- | ------------- | ------- |
-| state    | state value   | - |
-| actions  | Operation set | `Actions`  |
+| Property | Description   | Type      |
+|----------|---------------|-----------|
+| state    | state value   | -         |
+| actions  | Operation set | `Actions` |
 
 ### Actions
 
-| Property | Description                                          | Type                  |
-| -------- | ---------------------------------------------------- | --------------------- |
-| toggle   | Trigger state change                                 | `(state?: any) => void` |
-| setLeft  | Set defaultValue                                    | `() => void`            |
-| setRight | Set reverseValue                                    | `() => void`            |
+| Property | Description      | Type                    |
+|----------|------------------|-------------------------|
+| toggle   | Toggle state     | `() => void`            |
+| set      | Set state        | `(state: any) => void` |
+| setLeft  | Set defaultValue | `() => void`            |
+| setRight | Set reverseValue | `() => void`            |
diff --git a/packages/hooks/src/useToggle/index.ts b/packages/hooks/src/useToggle/index.ts
index 3730511c..e81d5eea 100644
--- a/packages/hooks/src/useToggle/index.ts
+++ b/packages/hooks/src/useToggle/index.ts
@@ -1,50 +1,42 @@
-import { useState, useMemo } from 'react';
+import { useMemo, useState } from 'react';
 
-type IState = string | number | boolean | undefined;
-
-export interface Actions<T = IState> {
+export interface Actions<T> {
   setLeft: () => void;
   setRight: () => void;
-  toggle: (value?: T) => void;
+  set: (value: T) => void;
+  toggle: () => void;
 }
 
 function useToggle<T = boolean | undefined>(): [boolean, Actions<T>];
 
-function useToggle<T = IState>(defaultValue: T): [T, Actions<T>];
+function useToggle<T>(defaultValue: T): [T, Actions<T>];
 
-function useToggle<T = IState, U = IState>(
-  defaultValue: T,
-  reverseValue: U,
-): [T | U, Actions<T | U>];
+function useToggle<T, U>(defaultValue: T, reverseValue: U): [T | U, Actions<T | U>];
 
-function useToggle<D extends IState = IState, R extends IState = IState>(
-  defaultValue: D = false as D,
-  reverseValue?: R,
-) {
+function useToggle<D, R>(defaultValue: D = false as unknown as D, reverseValue?: R) {
   const [state, setState] = useState<D | R>(defaultValue);
 
   const actions = useMemo(() => {
     const reverseValueOrigin = (reverseValue === undefined ? !defaultValue : reverseValue) as D | R;
 
-    // 切换返回值
-    const toggle = (value?: D | R) => {
-      // 强制返回状态值，适用于点击操作
-      if (value !== undefined) {
-        setState(value);
-        return;
-      }
-      setState((s) => (s === defaultValue ? reverseValueOrigin : defaultValue));
+    const toggle = () => setState((s) => (s === defaultValue ? reverseValueOrigin : defaultValue));
+
+    const set = (value: D | R) => {
+      setState(value);
     };
-    // 设置默认值
+
     const setLeft = () => setState(defaultValue);
-    // 设置取反值
     const setRight = () => setState(reverseValueOrigin);
+
     return {
       toggle,
+      set,
       setLeft,
       setRight,
     };
-  }, [defaultValue, reverseValue]);
+    // useToggle ignore value change
+    // }, [defaultValue, reverseValue]);
+  }, []);
 
   return [state, actions];
 }
diff --git a/packages/hooks/src/useToggle/index.zh-CN.md b/packages/hooks/src/useToggle/index.zh-CN.md
index 53e60a3c..b810fa89 100644
--- a/packages/hooks/src/useToggle/index.zh-CN.md
+++ b/packages/hooks/src/useToggle/index.zh-CN.md
@@ -10,6 +10,8 @@ group:
 
 # useToggle
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 用于在两个状态值间切换的 Hook。
 
 ## Examples
@@ -25,34 +27,35 @@ group:
 ## API
 
 ```typescript
-const [state, { toggle, setLeft, setRight }] = useToggle(
+const [state, { toggle, set, setLeft, setRight }] = useToggle(
   defaultValue?: boolean,
 );
 
-const [state,{ toggle, setLeft, setRight }] = useToggle(
-  defaultValue: any = false,
-  reverseValue?: any,
+const [state, { toggle, set, setLeft, setRight }] = useToggle(
+  defaultValue: any,
+  reverseValue: any,
 );
 ```
 
 ### Params
 
-| 参数           | 说明           | 类型                                       | 默认值   |
-| ------------ | ------------ | ---------------------------------------- | ----- |
-| defaultValue | 可选项，传入默认的状态值 | `number` \| `string` \| `boolean` \| `undefined` | `false` |
-| reverseValue | 可选项，传入取反的状态值 | `number` \| `string` \| `boolean` \| `undefined` | -     |
+| 参数         | 说明                     | 类型  | 默认值  |
+|--------------|--------------------------|-------|---------|
+| defaultValue | 可选项，传入默认的状态值 | `any` | `false` |
+| reverseValue | 可选项，传入取反的状态值 | `any` | -       |
 
 ### Result
 
-| 参数      | 说明   | 类型      |
-| ------- | ---- | ------- |
-| state   | 状态值  | - |
-| actions | 操作集合 | `Actions`  |
+| 参数    | 说明     | 类型      |
+|---------|----------|-----------|
+| state   | 状态值   | -         |
+| actions | 操作集合 | `Actions` |
 
 ### Actions
 
-| 参数       | 说明                        | 类型                    |
-| -------- | ------------------------- | --------------------- |
-| toggle   | 触发状态更改的函数，可以接受两个可选参数修改状态值 | `(state?: any) => void` |
-| setLeft  | 设置为 defaultValue          | `() => void`           |
-| setRight | 设置为 reverseValue          | `() => void`            |
+| 参数     | 说明                | 类型                    |
+|----------|---------------------|-------------------------|
+| toggle   | 切换 state          | `() => void`            |
+| set      | 修改 state          | `(state: any) => void` |
+| setLeft  | 设置为 defaultValue | `() => void`            |
+| setRight | 设置为 reverseValue | `() => void`            |
diff --git a/packages/hooks/src/useUnmount/demo/demo1.tsx b/packages/hooks/src/useUnmount/demo/demo1.tsx
index cb67ece9..98d25418 100644
--- a/packages/hooks/src/useUnmount/demo/demo1.tsx
+++ b/packages/hooks/src/useUnmount/demo/demo1.tsx
@@ -23,7 +23,7 @@ export default () => {
 
   return (
     <>
-      <button type="button" onClick={() => toggle()}>
+      <button type="button" onClick={toggle}>
         {state ? 'unmount' : 'mount'}
       </button>
       {state && <MyComponent />}
diff --git a/packages/hooks/src/useUnmountedRef/demo/demo1.tsx b/packages/hooks/src/useUnmountedRef/demo/demo1.tsx
index dc055e52..d50f6dcc 100644
--- a/packages/hooks/src/useUnmountedRef/demo/demo1.tsx
+++ b/packages/hooks/src/useUnmountedRef/demo/demo1.tsx
@@ -7,8 +7,8 @@
  */
 
 import { useBoolean, useUnmountedRef } from 'ahooks';
-import React, { useEffect, useState } from 'react';
 import { message } from 'antd';
+import React, { useEffect } from 'react';
 
 const MyComponent = () => {
   const unmountefRef = useUnmountedRef();
@@ -28,7 +28,7 @@ export default () => {
 
   return (
     <>
-      <button type="button" onClick={() => toggle()}>
+      <button type="button" onClick={toggle}>
         {state ? 'unmount' : 'mount'}
       </button>
       {state && <MyComponent />}


Test patch:
diff --git a/packages/hooks/src/useBoolean/__tests__/index.test.ts b/packages/hooks/src/useBoolean/__tests__/index.test.ts
index ae92a947..1b4c40e8 100644
--- a/packages/hooks/src/useBoolean/__tests__/index.test.ts
+++ b/packages/hooks/src/useBoolean/__tests__/index.test.ts
@@ -28,11 +28,11 @@ describe('useBoolean', () => {
     });
     expect(result.current[0]).toBeFalsy();
     act(() => {
-      result.current[1].toggle(false);
+      result.current[1].set(false);
     });
     expect(result.current[0]).toBeFalsy();
     act(() => {
-      result.current[1].toggle(true);
+      result.current[1].set(true);
     });
     expect(result.current[0]).toBeTruthy();
   });
diff --git a/packages/hooks/src/useToggle/__tests__/index.test.ts b/packages/hooks/src/useToggle/__tests__/index.test.ts
index 54db3e40..501a8f99 100644
--- a/packages/hooks/src/useToggle/__tests__/index.test.ts
+++ b/packages/hooks/src/useToggle/__tests__/index.test.ts
@@ -39,7 +39,7 @@ describe('useToggle', () => {
     callToggle(hook);
     expect(hook.result.current[0]).toEqual('World');
     act(() => {
-      hook.result.current[1].toggle('World');
+      hook.result.current[1].set('World');
     });
     expect(hook.result.current[0]).toEqual('World');
     callToggle(hook);