Skip to content

Instantly share code, notes, and snippets.

@cowboyd
Last active February 4, 2023 22:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cowboyd/0c27a93dd07b4fa45bb12cdc32439b1a to your computer and use it in GitHub Desktop.
Save cowboyd/0c27a93dd07b4fa45bb12cdc32439b1a to your computer and use it in GitHub Desktop.
A hypothetical restartable operation for @effection/react
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