Skip to content
Snippets Groups Projects
useAsync.js 932 B
Newer Older
import {useCallback, useEffect, useRef, useState} from "react";

const useAsync = (fn, params = [], immediate = true) => {
  const [status, setStatus] = useState("idle")
  const [value, setValue] = useState(null)
  const [error, setError] = useState(null)
  const mountedRef = useRef(true)


  const execute = useCallback(() => {
    setStatus("pending")
    setValue(null)
    setError(null)

    return fn(params)
      .then((val) => {
        if (!mountedRef.current) return null
        setValue(val)
        setStatus("success")
      })
      .catch((error) => {
        if (!mountedRef.current) return null
        setError(error)
        setStatus("error")
        throw error
      })
  }, [fn])

  useEffect(async () => {
    if (immediate){
      execute()
    }

    return () => {
      mountedRef.current = false
    }
  }, [execute, immediate])

  return { execute, status, value, error }
}

export default useAsync