Repository: alibaba/hooks
Pull request #1044 (2021-07-19 09:33:24)

optimize: side effect


Patch:
diff --git a/jest.config.js b/jest.config.js
index 2ee00495..21e4f1bc 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,6 +1,7 @@
 module.exports = {
   preset: 'ts-jest/presets/js-with-ts',
   clearMocks: true,
+  testPathIgnorePatterns: ['/.history/'],
   globals: {
     'ts-jest': {
       tsConfig: 'tsconfig.json',
diff --git a/packages/hooks/package.json b/packages/hooks/package.json
index 3d8828fe..8ca170bf 100644
--- a/packages/hooks/package.json
+++ b/packages/hooks/package.json
@@ -37,9 +37,7 @@
     "dayjs": "^1.9.1",
     "intersection-observer": "^0.7.0",
     "js-cookie": "^2.2.1",
-    "lodash.debounce": "^4.0.8",
-    "lodash.isequal": "^4.5.0",
-    "lodash.throttle": "^4.1.1",
+    "lodash": "^4.17.21",
     "resize-observer-polyfill": "^1.5.1",
     "screenfull": "^5.0.0"
   },
diff --git a/packages/hooks/src/useClickAway/index.en-US.md b/packages/hooks/src/useClickAway/index.en-US.md
index 571dc841..b9fad33f 100644
--- a/packages/hooks/src/useClickAway/index.en-US.md
+++ b/packages/hooks/src/useClickAway/index.en-US.md
@@ -34,7 +34,7 @@ Listen for click events outside the target element.
 
 ## API
 
-```ts
+```typescript
 type Target = Element | (() => Element) | React.MutableRefObject<Element>;
 
 useClickAway(
diff --git a/packages/hooks/src/useClickAway/index.zh-CN.md b/packages/hooks/src/useClickAway/index.zh-CN.md
index 8fc05d98..68da0fb9 100644
--- a/packages/hooks/src/useClickAway/index.zh-CN.md
+++ b/packages/hooks/src/useClickAway/index.zh-CN.md
@@ -35,7 +35,7 @@ group:
 
 ## API
 
-```ts
+```typescript
 type Target = Element | (() => Element) | React.MutableRefObject<Element>;
 
 useClickAway(
diff --git a/packages/hooks/src/useDebounce/index.en-US.md b/packages/hooks/src/useDebounce/index.en-US.md
index fcfd838d..e911d416 100644
--- a/packages/hooks/src/useDebounce/index.en-US.md
+++ b/packages/hooks/src/useDebounce/index.en-US.md
@@ -6,11 +6,12 @@ nav:
 group:
   title: SideEffect
   path: /side-effect
-  order: 7
 ---
 
 # useDebounce
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that handle the debounce value.
 
 ## Examples
@@ -21,7 +22,7 @@ A hook that handle the debounce value.
 
 ## API
 
-```javascript
+```typescript
 const debouncedValue = useDebounce(
   value: any,
   options?: Options
@@ -32,7 +33,7 @@ const debouncedValue = useDebounce(
 
 | Property | Description                                                  | Type      | Default |
 |----------|--------------------------------------------------------------|-----------|---------|
-| value    | value that requires debounce                                 | `any`     | -       |
+| value    | Value that requires debounce                                 | `any`     | -       |
 | options  | Config the debounce behavior. See the Options section below. | `Options` | `{}`    |
 
 ### Options
diff --git a/packages/hooks/src/useDebounce/index.ts b/packages/hooks/src/useDebounce/index.ts
index 13d031db..baff02e7 100644
--- a/packages/hooks/src/useDebounce/index.ts
+++ b/packages/hooks/src/useDebounce/index.ts
@@ -1,6 +1,6 @@
-import { useState, useEffect } from 'react';
+import { useEffect, useState } from 'react';
 import useDebounceFn from '../useDebounceFn';
-import { DebounceOptions } from './debounceOptions';
+import type { DebounceOptions } from './debounceOptions';
 
 function useDebounce<T>(value: T, options?: DebounceOptions) {
   const [debounced, setDebounced] = useState(value);
diff --git a/packages/hooks/src/useDebounce/index.zh-CN.md b/packages/hooks/src/useDebounce/index.zh-CN.md
index 163cf929..d57238e4 100644
--- a/packages/hooks/src/useDebounce/index.zh-CN.md
+++ b/packages/hooks/src/useDebounce/index.zh-CN.md
@@ -6,11 +6,12 @@ nav:
 group:
   title: SideEffect
   path: /side-effect
-  order: 7
 ---
 
 # useDebounce
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 用来处理防抖值的 Hook。
 
 ## 代码演示
@@ -21,7 +22,7 @@ group:
 
 ## API
 
-```javascript
+```typescript
 const debouncedValue = useDebounce(
   value: any,
   options?: Options
@@ -41,5 +42,5 @@ const debouncedValue = useDebounce(
 | 参数     | 说明                       | 类型      | 默认值  |
 |----------|----------------------------|-----------|---------|
 | wait     | 超时时间，单位为毫秒       | `number`  | `1000`  |
-| leading  | 是否在上升沿触发副作用函数 | `boolean` | `false` |
-| trailing | 是否在下降沿触发副作用函数 | `boolean` | `true`  |
+| leading  | 是否在延迟开始前调用函数 | `boolean` | `false` |
+| trailing | 是否在延迟开始后调用函数 | `boolean` | `true`  |
diff --git a/packages/hooks/src/useDebounceFn/demo/demo1.tsx b/packages/hooks/src/useDebounceFn/demo/demo1.tsx
index 7865a322..aa64c205 100644
--- a/packages/hooks/src/useDebounceFn/demo/demo1.tsx
+++ b/packages/hooks/src/useDebounceFn/demo/demo1.tsx
@@ -6,8 +6,8 @@
  * desc.zh-CN: 频繁调用 run，但只会在所有点击完成 500ms 后执行一次相关函数
  */
 
-import React, { useState } from 'react';
 import { useDebounceFn } from 'ahooks';
+import React, { useState } from 'react';
 
 export default () => {
   const [value, setValue] = useState(0);
diff --git a/packages/hooks/src/useDebounceFn/index.en-US.md b/packages/hooks/src/useDebounceFn/index.en-US.md
index 3f210de9..60f2123b 100644
--- a/packages/hooks/src/useDebounceFn/index.en-US.md
+++ b/packages/hooks/src/useDebounceFn/index.en-US.md
@@ -10,6 +10,8 @@ group:
 
 # useDebounceFn
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that handle the debounce function.
 
 ## Examples
@@ -20,10 +22,11 @@ A hook that handle the debounce function.
 
 ## API
 
-```javascript
+```typescript
 const {
   run,
-  cancel
+  cancel,
+  flush
 } = useDebounceFn(
   fn: (...args: any[]) => any,
   options?: Options
@@ -49,6 +52,6 @@ const {
 
 | Property | Description                               | Type         |
 |----------|-------------------------------------------|--------------|
-| run      | trigger fn, parameters will be send to fn | `(...args: any[]) => any` |
-| cancel   | cancel current debounce                   | `() => void` |
-| flush    | immediately invoke current debounce       | `() => void` |
+| run      | Trigger fn, parameters will be send to fn | `(...args: any[]) => any` |
+| cancel   | Cancel current debounce                   | `() => void` |
+| flush    | Immediately invoke current debounce       | `() => void` |
diff --git a/packages/hooks/src/useDebounceFn/index.ts b/packages/hooks/src/useDebounceFn/index.ts
index 74fcbd54..06c04152 100644
--- a/packages/hooks/src/useDebounceFn/index.ts
+++ b/packages/hooks/src/useDebounceFn/index.ts
@@ -1,18 +1,23 @@
-import debounce from 'lodash.debounce';
-import { useRef } from 'react';
-import useCreation from '../useCreation';
-import { DebounceOptions } from '../useDebounce/debounceOptions';
+import debounce from 'lodash/debounce';
+import { useMemo } from 'react';
+import type { DebounceOptions } from '../useDebounce/debounceOptions';
+import useLatest from '../useLatest';
 import useUnmount from '../useUnmount';
 
-type Fn = (...args: any) => any;
+type noop = (...args: any) => any;
 
-function useDebounceFn<T extends Fn>(fn: T, options?: DebounceOptions) {
-  const fnRef = useRef<T>(fn);
-  fnRef.current = fn;
+function useDebounceFn<T extends noop>(fn: T, options?: DebounceOptions) {
+  if (process.env.NODE_ENV === 'development') {
+    if (typeof fn !== 'function') {
+      console.error(`useDebounceFn expected parameter is a function, got ${typeof fn}`);
+    }
+  }
+
+  const fnRef = useLatest(fn);
 
   const wait = options?.wait ?? 1000;
 
-  const debounced = useCreation(
+  const debounced = useMemo(
     () =>
       debounce<T>(
         ((...args: any[]) => {
@@ -29,7 +34,7 @@ function useDebounceFn<T extends Fn>(fn: T, options?: DebounceOptions) {
   });
 
   return {
-    run: (debounced as unknown) as T,
+    run: debounced as unknown as T,
     cancel: debounced.cancel,
     flush: debounced.flush,
   };
diff --git a/packages/hooks/src/useDebounceFn/index.zh-CN.md b/packages/hooks/src/useDebounceFn/index.zh-CN.md
index 3ed44587..f84ac43e 100644
--- a/packages/hooks/src/useDebounceFn/index.zh-CN.md
+++ b/packages/hooks/src/useDebounceFn/index.zh-CN.md
@@ -10,6 +10,8 @@ group:
 
 # useDebounceFn
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 用来处理防抖函数的 Hook。
 
 ## 代码演示
@@ -20,10 +22,11 @@ group:
 
 ## API
 
-```javascript
+```typescript
 const {
   run,
-  cancel
+  cancel,
+  flush
 } = useDebounceFn(
   fn: (...args: any[]) => any,
   options?: Options
@@ -35,20 +38,21 @@ const {
 | 参数    | 说明                               | 类型                      | 默认值 |
 |---------|------------------------------------|---------------------------|--------|
 | fn      | 需要防抖执行的函数                 | `(...args: any[]) => any` | -      |
-| options | 配置防抖的行为，详见下面的 Options | `Options`                 | `{}`     |
+| options | 配置防抖的行为，详见下面的 Options | `Options`                 | `{}`   |
 
 ### Options
 
-| 参数     | 说明                       | 类型      | 默认值  |
-|----------|----------------------------|-----------|---------|
-| wait     | 超时时间，单位为毫秒       | `number`  | `1000`  |
-| leading  | 是否在上升沿触发副作用函数 | `boolean` | `false` |
-| trailing | 是否在下降沿触发副作用函数 | `boolean` | `true`  |
+| 参数     | 说明                     | 类型      | 默认值  |
+|----------|--------------------------|-----------|---------|
+| wait     | 超时时间，单位为毫秒     | `number`  | `1000`  |
+| leading  | 是否在延迟开始前调用函数 | `boolean` | `false` |
+| trailing | 是否在延迟开始后调用函数 | `boolean` | `true`  |
 
 ### Result
 
-| 参数   | 说明                               | 类型         |
-|--------|------------------------------------|--------------|
+| 参数   | 说明                               | 类型                      |
+|--------|------------------------------------|---------------------------|
 | run    | 触发执行 fn，函数参数将会传递给 fn | `(...args: any[]) => any` |
-| cancel | 取消当前防抖                       | `() => void` |
-| flush  | 当前防抖立即调用                   | `() => void` |
+| cancel | 取消当前防抖                       | `() => void`              |
+| flush  | 当前防抖函数立即调用               | `() => void`              |
+
diff --git a/packages/hooks/src/useDeepCompareEffect/index.tsx b/packages/hooks/src/useDeepCompareEffect/index.tsx
index 010cca71..d9a6e015 100644
--- a/packages/hooks/src/useDeepCompareEffect/index.tsx
+++ b/packages/hooks/src/useDeepCompareEffect/index.tsx
@@ -1,4 +1,4 @@
-import isEqual from 'lodash.isequal';
+import isEqual from 'lodash/isEqual';
 import { useEffect, useRef } from 'react';
 import type { DependencyList, EffectCallback } from 'react';
 
diff --git a/packages/hooks/src/useDeepCompareEffect/index.zh-CN.md b/packages/hooks/src/useDeepCompareEffect/index.zh-CN.md
index 408afe6c..b888fb43 100644
--- a/packages/hooks/src/useDeepCompareEffect/index.zh-CN.md
+++ b/packages/hooks/src/useDeepCompareEffect/index.zh-CN.md
@@ -12,7 +12,7 @@ group:
 
 <Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
 
-用法与 useEffect 一致，但 deps 通过 [lodash.isEqual](https://lodash.com/docs/4.17.15#isEqual) 进行深比较。
+用法与 useEffect 一致，但 deps 通过 [lodash isEqual](https://lodash.com/docs/4.17.15#isEqual) 进行深比较。
 
 ## 代码演示
 
diff --git a/packages/hooks/src/useInViewport/index.en-US.md b/packages/hooks/src/useInViewport/index.en-US.md
index 0325fe56..c7406df3 100644
--- a/packages/hooks/src/useInViewport/index.en-US.md
+++ b/packages/hooks/src/useInViewport/index.en-US.md
@@ -25,7 +25,7 @@ A hook to subscribe DOM element visibility change
 
 ## API
 
-```ts
+```typescript
 const inViewPort = useInViewport(target);
 ```
 
diff --git a/packages/hooks/src/useInViewport/index.zh-CN.md b/packages/hooks/src/useInViewport/index.zh-CN.md
index 38917d43..677d36d5 100644
--- a/packages/hooks/src/useInViewport/index.zh-CN.md
+++ b/packages/hooks/src/useInViewport/index.zh-CN.md
@@ -24,7 +24,7 @@ group:
 
 ## API
 
-```ts
+```typescript
 const inViewPort = useInViewport(target);
 ```
 
diff --git a/packages/hooks/src/useInterval/index.en-US.md b/packages/hooks/src/useInterval/index.en-US.md
index ee2bdddc..ffe34a85 100644
--- a/packages/hooks/src/useInterval/index.en-US.md
+++ b/packages/hooks/src/useInterval/index.en-US.md
@@ -10,6 +10,8 @@ group:
 
 # useInterval
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that can handle the setInterval timer function.
 
 ## Examples
@@ -25,7 +27,11 @@ A hook that can handle the setInterval timer function.
 ## API
 
 ```typescript
-useInterval(fn: () => void, interval: number, options?: Options);
+useInterval(
+  fn: () => void, 
+  interval?: number | null, 
+  options?: Options
+);
 ```
 
 ### Params
diff --git a/packages/hooks/src/useInterval/index.ts b/packages/hooks/src/useInterval/index.ts
index 595a4ef6..910fa221 100644
--- a/packages/hooks/src/useInterval/index.ts
+++ b/packages/hooks/src/useInterval/index.ts
@@ -1,4 +1,5 @@
-import { useEffect, useRef } from 'react';
+import { useEffect } from 'react';
+import useLatest from '../useLatest';
 
 function useInterval(
   fn: () => void,
@@ -6,19 +7,18 @@ function useInterval(
   options?: {
     immediate?: boolean;
   },
-): void {
+) {
   const immediate = options?.immediate;
 
-  const fnRef = useRef<() => void>();
-  fnRef.current = fn;
+  const fnRef = useLatest(fn);
 
   useEffect(() => {
     if (delay === undefined || delay === null) return;
     if (immediate) {
-      fnRef.current?.();
+      fnRef.current();
     }
     const timer = setInterval(() => {
-      fnRef.current?.();
+      fnRef.current();
     }, delay);
     return () => {
       clearInterval(timer);
diff --git a/packages/hooks/src/useInterval/index.zh-CN.md b/packages/hooks/src/useInterval/index.zh-CN.md
index 70992081..005773cc 100644
--- a/packages/hooks/src/useInterval/index.zh-CN.md
+++ b/packages/hooks/src/useInterval/index.zh-CN.md
@@ -10,6 +10,8 @@ group:
 
 # useInterval
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 一个可以处理 setInterval 的 Hook。
 
 ## 代码演示
@@ -25,7 +27,11 @@ group:
 ## API
 
 ```typescript
-useInterval(fn: () => void, interval: number, options?: Options);
+useInterval(
+  fn: () => void, 
+  interval?: number | null, 
+  options?: Options
+);
 ```
 
 ### Params
diff --git a/packages/hooks/src/useThrottle/index.en-US.md b/packages/hooks/src/useThrottle/index.en-US.md
index fecd4985..50963a13 100644
--- a/packages/hooks/src/useThrottle/index.en-US.md
+++ b/packages/hooks/src/useThrottle/index.en-US.md
@@ -6,11 +6,12 @@ nav:
 group:
   title: SideEffect
   path: /side-effect
-  order: 7
 ---
 
 # useThrottle
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that handle the throttle value.
 
 ## Examples
@@ -32,7 +33,7 @@ const throttledValue = useThrottle(
 
 | Property | Description                                                  | Type      | Default |
 |----------|--------------------------------------------------------------|-----------|---------|
-| value    | value that requires throttle                                 | `any`     | -       |
+| value    | Value that requires throttle                                 | `any`     | -       |
 | options  | Config the throttle behavior. See the Options section below. | `Options` | `{}`    |
 
 ### Options
diff --git a/packages/hooks/src/useThrottle/index.ts b/packages/hooks/src/useThrottle/index.ts
index 50a2ee4e..07d960d2 100644
--- a/packages/hooks/src/useThrottle/index.ts
+++ b/packages/hooks/src/useThrottle/index.ts
@@ -1,6 +1,6 @@
-import { useState, useEffect } from 'react';
+import { useEffect, useState } from 'react';
 import useThrottleFn from '../useThrottleFn';
-import { ThrottleOptions } from './throttleOptions';
+import type { ThrottleOptions } from './throttleOptions';
 
 function useThrottle<T>(value: T, options?: ThrottleOptions) {
   const [throttled, setThrottled] = useState(value);
diff --git a/packages/hooks/src/useThrottle/index.zh-CN.md b/packages/hooks/src/useThrottle/index.zh-CN.md
index 20849cbf..788aade1 100644
--- a/packages/hooks/src/useThrottle/index.zh-CN.md
+++ b/packages/hooks/src/useThrottle/index.zh-CN.md
@@ -6,11 +6,12 @@ nav:
 group:
   title: SideEffect
   path: /side-effect
-  order: 7
 ---
 
 # useThrottle
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 用来处理节流值的 Hook。
 
 ## 代码演示
@@ -38,8 +39,8 @@ const throttledValue = useThrottle(
 
 ### Options
 
-| 参数     | 说明                       | 类型      | 默认值 |
-|----------|----------------------------|-----------|--------|
-| wait     | 超时时间，单位为毫秒       | `number`  | `1000` |
-| leading  | 是否在上升沿触发副作用函数 | `boolean` | `true` |
-| trailing | 是否在下降沿触发副作用函数 | `boolean` | `true` |
+| 参数     | 说明                     | 类型      | 默认值 |
+|----------|--------------------------|-----------|--------|
+| wait     | 超时时间，单位为毫秒     | `number`  | `1000` |
+| leading  | 是否在延迟开始前调用函数 | `boolean` | `true` |
+| trailing | 是否在延迟开始后调用函数 | `boolean` | `true` |
\ No newline at end of file
diff --git a/packages/hooks/src/useThrottleFn/index.en-US.md b/packages/hooks/src/useThrottleFn/index.en-US.md
index f6e7787b..e43466db 100644
--- a/packages/hooks/src/useThrottleFn/index.en-US.md
+++ b/packages/hooks/src/useThrottleFn/index.en-US.md
@@ -10,6 +10,8 @@ group:
 
 # useThrottleFn
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that handle the throttle function.
 
 ## Examples
@@ -23,7 +25,8 @@ A hook that handle the throttle function.
 ```typescript
 const {
   run,
-  cancel
+  cancel,
+  flush
 } = useThrottleFn(
   fn: (...args: any[]) => any,
   options?: Options
@@ -49,6 +52,6 @@ const {
 
 | Property | Description                               | Type                      |
 |----------|-------------------------------------------|---------------------------|
-| run      | trigger fn, parameters will be send to fn | `(...args: any[]) => any` |
-| cancel   | cancel current throttle                   | `() => void`              |
-| flush    | immediately invoke current throttle       | `() => void`              |
+| run      | Trigger fn, parameters will be send to fn | `(...args: any[]) => any` |
+| cancel   | Cancel current throttle                   | `() => void`              |
+| flush    | Immediately invoke current throttle       | `() => void`              |
diff --git a/packages/hooks/src/useThrottleFn/index.ts b/packages/hooks/src/useThrottleFn/index.ts
index 2b4f5acc..ad427137 100644
--- a/packages/hooks/src/useThrottleFn/index.ts
+++ b/packages/hooks/src/useThrottleFn/index.ts
@@ -1,18 +1,23 @@
-import throttle from 'lodash.throttle';
-import { useRef } from 'react';
-import useCreation from '../useCreation';
-import { ThrottleOptions } from '../useThrottle/throttleOptions';
+import throttle from 'lodash/throttle';
+import { useMemo } from 'react';
+import useLatest from '../useLatest';
+import type { ThrottleOptions } from '../useThrottle/throttleOptions';
 import useUnmount from '../useUnmount';
 
-type Fn = (...args: any) => any;
+type noop = (...args: any) => any;
 
-function useThrottleFn<T extends Fn>(fn: T, options?: ThrottleOptions) {
-  const fnRef = useRef<T>(fn);
-  fnRef.current = fn;
+function useThrottleFn<T extends noop>(fn: T, options?: ThrottleOptions) {
+  if (process.env.NODE_ENV === 'development') {
+    if (typeof fn !== 'function') {
+      console.error(`useThrottleFn expected parameter is a function, got ${typeof fn}`);
+    }
+  }
+
+  const fnRef = useLatest(fn);
 
   const wait = options?.wait ?? 1000;
 
-  const throttled = useCreation(
+  const throttled = useMemo(
     () =>
       throttle<T>(
         ((...args: any[]) => {
@@ -29,7 +34,7 @@ function useThrottleFn<T extends Fn>(fn: T, options?: ThrottleOptions) {
   });
 
   return {
-    run: (throttled as unknown) as T,
+    run: throttled as unknown as T,
     cancel: throttled.cancel,
     flush: throttled.flush,
   };
diff --git a/packages/hooks/src/useThrottleFn/index.zh-CN.md b/packages/hooks/src/useThrottleFn/index.zh-CN.md
index 37536123..7175bb39 100644
--- a/packages/hooks/src/useThrottleFn/index.zh-CN.md
+++ b/packages/hooks/src/useThrottleFn/index.zh-CN.md
@@ -10,6 +10,8 @@ group:
 
 # useThrottleFn
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 用来处理节流函数的 Hook。
 
 ## 代码演示
@@ -23,7 +25,8 @@ group:
 ```typescript
 const {
   run,
-  cancel
+  cancel,
+  flush
 } = useThrottleFn(
   fn: (...args: any[]) => any,
   options?: Options
@@ -42,8 +45,8 @@ const {
 | 参数     | 说明                       | 类型      | 默认值 |
 |----------|----------------------------|-----------|--------|
 | wait     | 超时时间，单位为毫秒       | `number`  | `1000` |
-| leading  | 是否在上升沿触发副作用函数 | `boolean` | `true` |
-| trailing | 是否在下降沿触发副作用函数 | `boolean` | `true` |
+| leading  | 是否在延迟开始前调用函数 | `boolean` | `true` |
+| trailing | 是否在延迟开始后调用函数 | `boolean` | `true` |
 
 ### Result
 
diff --git a/packages/hooks/src/useTimeout/demo/demo1.tsx b/packages/hooks/src/useTimeout/demo/demo1.tsx
index 14de8c35..fe083934 100644
--- a/packages/hooks/src/useTimeout/demo/demo1.tsx
+++ b/packages/hooks/src/useTimeout/demo/demo1.tsx
@@ -3,7 +3,7 @@
  * desc: Execute once after 3000ms
  *
  * title.zh-CN: 基础用法
- * desc.zh-CN: 3000ms后执行一次
+ * desc.zh-CN: 3000ms 后执行一次
  */
 
 import React, { useState } from 'react';
@@ -17,7 +17,7 @@ export default () => {
 
   return (
     <div>
-      <p style={{ marginTop: 16 }}> {state} </p>
+      {state}
     </div>
   );
 };
diff --git a/packages/hooks/src/useTimeout/index.en-US.md b/packages/hooks/src/useTimeout/index.en-US.md
index e639062b..a2cbab4b 100644
--- a/packages/hooks/src/useTimeout/index.en-US.md
+++ b/packages/hooks/src/useTimeout/index.en-US.md
@@ -10,6 +10,8 @@ group:
 
 # useTimeout
 
+<Tag lang="en-US" tags="ssr&crossPlatform"></Tag>
+
 A hook that can handle the setTimeout timer function.
 
 ## Examples
@@ -18,16 +20,18 @@ A hook that can handle the setTimeout timer function.
 
 <code src="./demo/demo1.tsx" />
 
-
 ## API
 
 ```typescript
-useTimeout(fn: () => void, delay: number | undefined | null);
+useTimeout(
+  fn: () => void, 
+  delay?: number | null
+);
 ```
 
 ### Params
 
 | Property | Description | Type |
 |----------|--------------------------------------|----------------------|
-| fn  | Is the function you want to execute after the expiration time (delay milliseconds) | `() => void` |
+| fn  | The function to setTimeout | `() => void` |
 | delay | The time to wait, in milliseconds. If delay is `null` or `undefined`, the timer will stop. | `number` \| `undefined` \| `null` |
diff --git a/packages/hooks/src/useTimeout/index.ts b/packages/hooks/src/useTimeout/index.ts
index e80e9ad5..6ad4dadf 100644
--- a/packages/hooks/src/useTimeout/index.ts
+++ b/packages/hooks/src/useTimeout/index.ts
@@ -1,18 +1,18 @@
 import { useEffect } from 'react';
-import useMemoizedFn from '../useMemoizedFn';
+import useLatest from '../useLatest';
 
 function useTimeout(fn: () => void, delay: number | null | undefined): void {
-  const timerFn = useMemoizedFn(fn);
+  const fnRef = useLatest(fn);
 
   useEffect(() => {
     if (delay === undefined || delay === null) return;
     const timer = setTimeout(() => {
-      timerFn();
+      fnRef.current();
     }, delay);
     return () => {
       clearTimeout(timer);
     };
-  }, [delay, timerFn]);
+  }, [delay]);
 }
 
 export default useTimeout;
diff --git a/packages/hooks/src/useTimeout/index.zh-CN.md b/packages/hooks/src/useTimeout/index.zh-CN.md
index 147ebbe1..7b04be21 100644
--- a/packages/hooks/src/useTimeout/index.zh-CN.md
+++ b/packages/hooks/src/useTimeout/index.zh-CN.md
@@ -10,6 +10,8 @@ group:
 
 # useTimeout
 
+<Tag lang="zh-CN" tags="ssr&crossPlatform"></Tag>
+
 一个可以处理 setTimeout 计时器函数的 Hook。
 
 ## 代码演示
@@ -18,16 +20,18 @@ group:
 
 <code src="./demo/demo1.tsx" />
 
-
 ## API
 
 ```typescript
-useTimeout(fn: () => void, delay: number | undefined | null);
+useTimeout(
+  fn: () => void, 
+  delay?: number | null
+);
 ```
 
-### 参数
+### Params
 
 | 参数 | 说明 | 类型 |
 |------|---------------------------|--------|
-| fn   | 是你想要在到期时间(delay毫秒)之后执行的函数 | `() => void` |
-| delay | 到期时间（单位为毫秒），当取值为 `null` 或 `undefined` 时会停止计时器 | `number` \| `undefined` \| `null` |
+| fn   | 执行函数 | `() => void` |
+| delay | 定时时间（单位为毫秒），当取值为 `null` 或 `undefined` 时会停止计时器 | `number` \| `undefined` \| `null` |
diff --git a/packages/use-request/src/useAsync.ts b/packages/use-request/src/useAsync.ts
index 1057d589..7206bf99 100644
--- a/packages/use-request/src/useAsync.ts
+++ b/packages/use-request/src/useAsync.ts
@@ -1,5 +1,5 @@
-import debounce from 'lodash.debounce';
-import throttle from 'lodash.throttle';
+import debounce from 'lodash/debounce';
+import throttle from 'lodash/throttle';
 import { useCallback, useEffect, useRef, useState } from 'react';
 import {
   BaseOptions,


Test patch:
diff --git a/packages/hooks/src/useDebounceFn/__tests__/index.test.ts b/packages/hooks/src/useDebounceFn/__tests__/index.test.ts
index caa6e782..b0107e02 100644
--- a/packages/hooks/src/useDebounceFn/__tests__/index.test.ts
+++ b/packages/hooks/src/useDebounceFn/__tests__/index.test.ts
@@ -1,6 +1,6 @@
 import { act, renderHook, RenderHookResult } from '@testing-library/react-hooks';
-import useDebounceFn from '../index';
 import { sleep } from '../../utils/testingHelpers';
+import useDebounceFn from '../index';
 
 interface ParamsObj {
   fn: (...arg: any) => any;