Skip to content

Commit

Permalink
feat: useThrottle & useThrottleFn
Browse files Browse the repository at this point in the history
  • Loading branch information
AmbitionsXXXV committed Nov 30, 2023
1 parent 4b2e408 commit 047c481
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 1 deletion.
5 changes: 5 additions & 0 deletions config/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const menus = [
{ title: 'useDebounce', link: '/hooks/use-debounce' },
{ title: 'useResetState', link: '/hooks/use-reset-state' },
{ title: 'useSet', link: '/hooks/use-set' },
{ title: 'useThrottle', link: '/hooks/use-throttle' },
{ title: 'useToggle', link: '/hooks/use-toggle' },
{ title: 'useUpdate', link: '/hooks/use-update' },
],
Expand All @@ -42,6 +43,10 @@ export const menus = [
title: 'useDebounceFn',
link: '/hooks/use-debounce-fn',
},
{
title: 'useThrottleFn',
link: '/hooks/use-throttle-fn',
},
{ title: 'useUpdateEffect', link: '/hooks/use-update-effect' },
],
},
Expand Down
2 changes: 1 addition & 1 deletion packages/hooks/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "etc-hooks",
"version": "0.4.9",
"version": "0.5.0",
"description": "Etcetera React 业务 Hooks",
"keywords": [
"etcetera",
Expand Down
4 changes: 4 additions & 0 deletions packages/hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import useOs from './useOs'
import useRequest from './useRequest'
import useResetState from './useResetState'
import useSet from './useSet'
import useThrottle from './useThrottle/index'
import useThrottleFn from './useThrottleFn/index'
import useTitle from './useTitle'
import useToggle from './useToggle'
import useUnmount from './useUnmount'
Expand All @@ -40,6 +42,8 @@ export {
useRequest,
useResetState,
useSet,
useThrottle,
useThrottleFn,
useTitle,
useToggle,
useUnmount,
Expand Down
29 changes: 29 additions & 0 deletions packages/hooks/src/useThrottle/example/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* title: Default usage
* desc: ThrottledValue will change every 500ms.
*
* title.zh-CN: 基础用法
* desc.zh-CN: ThrottledValue 每隔 500ms 变化一次。
*/

import { Input } from 'antd'
import { useThrottle } from 'etc-hooks'
import React, { useState } from 'react'

export default () => {
const [value, setValue] = useState<string>()
const throttledValue = useThrottle(value, { wait: 500 })

return (
<div>
<Input
value={value}
style={{ width: 280 }}
placeholder="Typed value"
onChange={(e) => setValue(e.target.value)}
/>

<p className="mt-4">throttledValue: {throttledValue}</p>
</div>
)
}
38 changes: 38 additions & 0 deletions packages/hooks/src/useThrottle/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
nav:
path: /hooks
---

# useThrottle

用来处理节流值的 Hook。

## 代码演示

### 基础用法

<code src="./example/example.tsx"></code>

## API

```typescript
const throttledValue = useThrottle(
value: any,
options?: Options
);
```

### Params

| 参数 | 说明 | 类型 | 默认值 |
| ------- | -------------- | --------- | ------ |
| value | 需要节流的值 | `any` | - |
| options | 配置节流的行为 | `Options` | - |

### Options

| 参数 | 说明 | 类型 | 默认值 |
| -------- | ------------------------ | --------- | ------ |
| wait | 等待时间,单位为毫秒 | `number` | `1000` |
| leading | 是否在延迟开始前调用函数 | `boolean` | `true` |
| trailing | 是否在延迟开始后调用函数 | `boolean` | `true` |
19 changes: 19 additions & 0 deletions packages/hooks/src/useThrottle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useEffect, useState } from 'react'
import useThrottleFn from '../useThrottleFn'
import type { ThrottleOptions } from './throttleOptions'

function useThrottle<T>(value: T, options?: ThrottleOptions) {
const [throttled, setThrottled] = useState(value)

const { run } = useThrottleFn(() => {
setThrottled(value)
}, options)

useEffect(() => {
run()
}, [value])

return throttled
}

export default useThrottle
5 changes: 5 additions & 0 deletions packages/hooks/src/useThrottle/throttleOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ThrottleOptions {
wait?: number
leading?: boolean
trailing?: boolean
}
29 changes: 29 additions & 0 deletions packages/hooks/src/useThrottleFn/example/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* title: Default usage
* desc: Frequent calls run, but the function is only executed every 500ms.
*
* title.zh-CN: 基础用法
* desc.zh-CN: 频繁调用 run,但只会每隔 500ms 执行一次相关函数。
*/

import { Button } from 'antd'
import { useThrottleFn } from 'etc-hooks'
import React, { useState } from 'react'

export default () => {
const [value, setValue] = useState(0)
const { run } = useThrottleFn(
() => {
setValue(value + 1)
},
{ wait: 500 },
)

return (
<div>
<p className="mt-4"> Clicked count: {value} </p>

<Button onClick={run}>Click fast!</Button>
</div>
)
}
50 changes: 50 additions & 0 deletions packages/hooks/src/useThrottleFn/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
nav:
path: /hooks
---

# useThrottleFn

用来处理函数节流的 Hook。

## 代码演示

### 基础用法

<code src="./example/example.tsx"></code>

## API

```typescript
const {
run,
cancel,
flush
} = useThrottleFn(
fn: (...args: any[]) => any,
options?: Options
);
```

### Params

| 参数 | 说明 | 类型 | 默认值 |
| ------- | -------------- | ------------------------- | ------ |
| fn | 需要节流的函数 | `(...args: any[]) => any` | - |
| options | 配置节流的行为 | `Options` | - |

### Options

| 参数 | 说明 | 类型 | 默认值 |
| -------- | ------------------------ | --------- | ------ |
| wait | 等待时间,单位为毫秒 | `number` | `1000` |
| leading | 是否在延迟开始前调用函数 | `boolean` | `true` |
| trailing | 是否在延迟开始后调用函数 | `boolean` | `true` |

### Result

| 参数 | 说明 | 类型 |
| ------ | ---------------------------------- | ------------------------- |
| run | 触发执行 fn,函数参数将会传递给 fn | `(...args: any[]) => any` |
| cancel | 取消当前节流 | `() => void` |
| flush | 当前节流立即调用 | `() => void` |
47 changes: 47 additions & 0 deletions packages/hooks/src/useThrottleFn/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { throttle } from 'lodash-es'
import { useMemo } from 'react'
import useLatest from '../useLatest'
import type { ThrottleOptions } from '../useThrottle/throttleOptions'
import useUnmount from '../useUnmount'
import { isFunction } from '../utils'
import isDev from '../utils/isDev'

type noop = (...args: any[]) => any

function useThrottleFn<T extends noop>(fn: T, options?: ThrottleOptions) {
if (isDev) {
if (!isFunction(fn)) {
console.error(
`useThrottleFn expected parameter is a function, got ${typeof fn}`,
)
}
}

const fnRef = useLatest(fn)

const wait = options?.wait ?? 1000

const throttled = useMemo(
() =>
throttle(
(...args: Parameters<T>): ReturnType<T> => {
return fnRef.current(...args)
},
wait,
options,
),
[],
)

useUnmount(() => {
throttled.cancel()
})

return {
run: throttled,
cancel: throttled.cancel,
flush: throttled.flush,
}
}

export default useThrottleFn

0 comments on commit 047c481

Please sign in to comment.