Last active
February 4, 2023 22:59
-
-
Save cowboyd/0c27a93dd07b4fa45bb12cdc32439b1a to your computer and use it in GitHub Desktop.
A hypothetical restartable operation for @effection/react
This file contains hidden or 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
import { useCallback, useMemo } from 'react'; | |
import { Task, Operation, createQueue, spawn } from 'effection'; | |
import { useOperation } from './use-operation'; | |
/** | |
* Create an event handler that can be used for UI events safely. | |
* If the handler is invoked more than once, the existing task is halted | |
* and a new one is spawned. E.g. | |
* | |
* const AutoCompleter = ({ searchFn }) => { | |
* const [results, setResults] = useState([]); | |
* const search = useHandler(function*(event) { | |
* // give user a 200ms window to enter more text before firing search | |
* yield sleep(200); | |
* setResults(yield searchFn(event.text)); | |
* }); | |
* return ( | |
* <div> | |
* <input type="text" onKepress={search}/> | |
* <ShowResults results={results}/> | |
* </div> | |
* ); | |
* } | |
*/ | |
export function useHandler<T>(perform: (value: T) => Operation<unknown>, dependencies: unknown[] = []): (t: T) => void { | |
let queue = useMemo(() => createQueue<T>(), dependencies); | |
useOperation(function*() { | |
let current: Task | null = null; | |
yield queue.forEach(function*(value) { | |
if (current) { | |
yield current.halt(); | |
} | |
current = yield spawn(perform(value)) | |
}) | |
}, dependencies); | |
return useCallback((value: T) => queue.send(value), dependencies); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment