Appearance
useWatchTriggerable
Watch that can be triggered manually
Demo
Usage
A watch wrapper that supports manual triggering of WatchCallback, which returns an additional trigger to execute a WatchCallback immediately.
tsx
import { useWatchTriggerable } from '@reause/shared'
import { useState } from 'react'
const [source, setSource] = useState(0)
const { trigger, ignoreUpdates } = useWatchTriggerable(
source,
v => console.log(`Changed to ${v}!`),
)
setSource(1) // logs (after commit): Changed to 1!
// Execution of WatchCallback via `trigger` does not require waiting
trigger() // logs: Changed to 1!onCleanup
When you want to manually call a watch that uses the onCleanup parameter; simply taking the WatchCallback out and calling it doesn't make it easy to implement the onCleanup parameter.
Using useWatchTriggerable will solve this problem.
tsx
import { useWatchTriggerable } from '@reause/shared'
import { useState } from 'react'
const [source, setSource] = useState(0)
const { trigger } = useWatchTriggerable(
source,
async (v, _, onCleanup) => {
let canceled = false
onCleanup(() => canceled = true)
await new Promise(resolve => setTimeout(resolve, 500))
if (canceled)
return
console.log(`The value is "${v}"\n`)
},
)
setSource(1) // no log
await trigger() // logs (after 500 ms): The value is "1"Type Declarations
Toggle
ts
export type OnCleanup = (cleanupFn: () => void) => void
export interface UseWatchTriggerableCallback<V = any, OV = any, R = void> {
(value: V, oldValue: OV, onCleanup: OnCleanup): R;
}
export type UseWatchTriggerableOldValues<T extends readonly any[]> = {
[K in keyof T]: T[K] | undefined;
}
export interface UseWatchTriggerableReturn<R = void> {
trigger: () => R;
ignoreUpdates: IgnoredUpdater;
ignorePrevAsyncUpdates: () => void;
stop: () => void;
}
export interface UseWatchTriggerableOptions {
immediate?: boolean;
}
export type IgnoredUpdater = (updater: () => void) => void
export interface UseWatchIgnorableReturn {
ignoreUpdates: IgnoredUpdater;
ignorePrevAsyncUpdates: IgnoredPrevAsyncUpdates;
stop: () => void;
}
export function useWatchTriggerable<T extends any[], R>(source: readonly [
...T
], callback: UseWatchTriggerableCallback<[
...T
], UseWatchTriggerableOldValues<[
...T
]>, R>, options?: UseWatchTriggerableOptions): UseWatchTriggerableReturn<R>
export function useWatchTriggerable<T, R>(source: T, callback: UseWatchTriggerableCallback<T, T | undefined, R>, options?: UseWatchTriggerableOptions): UseWatchTriggerableReturn<R>