Skip to content

Instantly share code, notes, and snippets.

@Phryxia
Created November 17, 2022 06:28
Show Gist options
  • Select an option

  • Save Phryxia/b03f8bc87998f4cc3c426efe3fba565f to your computer and use it in GitHub Desktop.

Select an option

Save Phryxia/b03f8bc87998f4cc3c426efe3fba565f to your computer and use it in GitHub Desktop.
TypeScript implementation of useAsyncEffect hook for React
import { DependencyList, EffectCallback, useEffect } from 'react'
type Destructor = () => void
type AsyncDestructor = () => Promise<void>
type AsyncEffectCallback = () => Promise<void | Destructor | AsyncDestructor>
export function useAsyncEffect(callback: EffectCallback | AsyncEffectCallback, deps?: DependencyList) {
useEffect(() => {
const mayPromise = callback()
if (mayPromise instanceof Promise) {
return () => void mayPromise.then(cleanup => cleanup?.())
}
return mayPromise
}, deps)
}
@Phryxia
Copy link
Author

Phryxia commented Nov 17, 2022

Fetching asynchronous API inside of normal useEffect usually really sucks. Still it's possible with vanilla React, but it's very verbose and reduces development experience.

useEffect(() => {
  async function foo() {
    await bar()
  }
  foo()
}, [blah])

And even more, cleanup is more tricky when cleanup function depends on the return value of asynchonous things.

This custom hook wraps useEffect effectively. Also this hook is intended to replace normal useEffect since it works well with normal synchronous callback. Also asynchronous clean up is also available, though it should be carefully used.

useAsyncEffect(async () => {
  // simply use async-await syntax sugar inside of async function
  await bar()

  // can return any valid desturctor (=clean up) function even with the asynchronous things.
  return async () => await baz()
}, [])

Note that these pre-defined types are based on React type declaration. The reason why I redeclared these is because some of them are not accessible from outside of the module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment