Skip to content

Instantly share code, notes, and snippets.

@dobernike
Created December 26, 2020 10:35
Show Gist options
  • Select an option

  • Save dobernike/ab3d20cf8147530627886385c81e8542 to your computer and use it in GitHub Desktop.

Select an option

Save dobernike/ab3d20cf8147530627886385c81e8542 to your computer and use it in GitHub Desktop.
import { DependencyList, useEffect } from 'react'
type Effect<T> = (isMounted: () => boolean) => T | PromiseLike<T>
type Destroy<T> = DependencyList | ((result: T) => void)
function hasDestroy<T>(destroy?: Destroy<T>): destroy is (result: T) => void {
return typeof destroy === 'function'
}
export function useAsyncEffect<T = unknown>(
effect: Effect<T>,
inputs?: DependencyList,
destroy?: Destroy<T>,
) {
useEffect(function () {
let result: T
let mounted = true
const maybePromise = effect(() => mounted)
Promise.resolve(maybePromise).then(value => {
result = value
})
return () => {
mounted = false
if (hasDestroy(destroy)) {
return destroy(result)
}
}
}, inputs)
}
// possible usage
useAsyncEffect(async () => {
if (!changes) setLoaded(false)
const ch = api.changes(
// some changes
)
setChanges(ch)
setLoaded(true)
}, [api])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment