-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add new Hook
useVersionedAction
to run versioned action
- Loading branch information
Showing
5 changed files
with
191 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { Button, Card, KeyValue, OTP, Zone, wait as mockFetch } from '@/components' | ||
import { useSafeState, useVersionedAction } from '@shined/react-use' | ||
|
||
export function App() { | ||
const [value, setValue] = useSafeState('Click to Fetch') | ||
const [incVersion, runVersionedAction] = useVersionedAction() | ||
|
||
const fetch = async () => { | ||
await mockFetch(300 + Math.random() * 1_000) | ||
setValue(OTP()) | ||
} | ||
|
||
const versionedFetch = async () => { | ||
const version = incVersion() | ||
await mockFetch(300 + Math.random() * 1_000) | ||
runVersionedAction(version, () => { | ||
setValue(OTP()) | ||
}) | ||
} | ||
|
||
return ( | ||
<Card> | ||
<KeyValue label="Value" value={value} /> | ||
<Zone> | ||
<Button onClick={fetch}>Fetch</Button> | ||
<Button onClick={versionedFetch}>Versioned Fetch</Button> | ||
</Zone> | ||
</Card> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
--- | ||
category: Utilities | ||
features: ['LowLevel'] | ||
--- | ||
|
||
# useVersionedAction | ||
|
||
import { HooksType, Since } from '@/components' | ||
|
||
<HooksType {...frontmatter} /> | ||
|
||
<Since version='v1.7.0' /> | ||
|
||
A low-level React Hook designed to facilitate the use of "versioned" actions, commonly employed in asynchronous scenarios for filtering operations to ensure only the latest action is executed. | ||
|
||
## Scenes \{#scenes} | ||
|
||
- **Asynchronous operation filtering**: Handling multiple asynchronous operations, executing only the latest operation, ignoring "expired" ones. | ||
|
||
## Demo \{#demo} | ||
|
||
import { App } from './demo' | ||
|
||
<App /> | ||
|
||
## Usage \{#usage} | ||
|
||
When `doSomething()` is called consecutively, only the most recent operation is executed, avoiding "expired" operations that could lead to screen flicker or unexpected results. | ||
|
||
```tsx | ||
const [incVersion, runVersionedAction] = useVersionedAction() | ||
|
||
const doSomething = async () => { | ||
// Increment the version number with incVersion() | ||
const version = incVersion() | ||
|
||
// Asynchronous operation, like fetching data | ||
const result = await fetchSomething() | ||
|
||
// Ensure only the latest action is executed with runVersionedAction() | ||
runVersionedAction(version, async () => { | ||
setResult(result) | ||
}) | ||
} | ||
``` | ||
|
||
## Source \{#source} | ||
|
||
import { Source } from '@/components' | ||
|
||
<Source /> | ||
|
||
## API | ||
|
||
```tsx | ||
const [incVersion, runVersionedAction] = useVersionedAction() | ||
``` | ||
|
||
### Returns \{#returns} | ||
|
||
```tsx | ||
export type UseVersionedActionReturns = readonly [ | ||
/** | ||
* Increment the version number and return the current version number | ||
*/ | ||
incVersion: () => number, | ||
/** | ||
* Executes the versioned operation, only if the version number matches, ensuring that only the latest action is executed | ||
*/ | ||
runVersionedAction: <T extends AnyFunc>(version: number, handler: T) => ReturnType<T> | undefined, | ||
] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
packages/react-use/src/use-versioned-action/index.zh-cn.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
--- | ||
category: Utilities | ||
features: ['LowLevel'] | ||
--- | ||
|
||
# useVersionedAction | ||
|
||
import { HooksType, Since } from '@/components' | ||
|
||
<HooksType {...frontmatter} /> | ||
|
||
<Since version='v1.7.0' /> | ||
|
||
一个用于帮助使用“带版本”动作的 React Hook,常用于异步场景下进行操作过滤,以保证只执行最新的操作。 | ||
|
||
## 场景 \{#scenes} | ||
|
||
- **异步操作过滤**:处理多个异步操作,只执行最新的操作,忽略“已过期”的操作。 | ||
|
||
## 演示 \{#demo} | ||
|
||
快速点击下面的两个按钮,只有“带版本”的操作会忽略“已过期”的操作,确保只执行最新的操作。 | ||
|
||
import { App } from './demo' | ||
|
||
<App /> | ||
|
||
## 用法 \{#usage} | ||
|
||
当 `doSomething()` 被连续调用时,只有最新的操作会被执行,而不会出现“过期”的操作导致的「屏闪」或者「非预期结果」。 | ||
|
||
```tsx | ||
const [incVersion, runVersionedAction] = useVersionedAction() | ||
|
||
const doSomething = async () => { | ||
// 通过 incVersion() 来增加版本号 | ||
const version = incVersion() | ||
|
||
// 异步操作,如请求数据 | ||
const result = await fetchSomething() | ||
|
||
// 通过 runVersionedAction() 来确保只执行最新的操作 | ||
runVersionedAction(version, async () => { | ||
setResult(result) | ||
}) | ||
} | ||
``` | ||
|
||
## 源码 \{#source} | ||
|
||
import { Source } from '@/components' | ||
|
||
<Source /> | ||
|
||
## API | ||
|
||
```tsx | ||
const [incVersion, runVersionedAction] = useVersionedAction() | ||
``` | ||
|
||
### 返回值 \{#returns} | ||
|
||
```tsx | ||
export type UseVersionedActionReturns = readonly [ | ||
/** | ||
* 增加版本号,并返回当前版本号 | ||
*/ | ||
incVersion: () => number, | ||
/** | ||
* 执行带版本号的操作,只有当版本号匹配时才会执行,以确保只执行最新的操作 | ||
*/ | ||
runVersionedAction: <T extends AnyFunc>(version: number, handler: T) => ReturnType<T> | undefined, | ||
] | ||
``` |