react-use-async-fn
TypeScript icon, indicating that this package has built-in type declarations

0.2.0 • Public • Published

React Use Async Fn

BUILD Coverage Status License npm npm package minimized gzipped size (select exports)

React hook for managing the state of async function and abortable async functions

Features

  • Execute and track not only API requests but any async functions.
  • Abort async functions. Can be used to abort fetch API calls.
  • Simple API to await async function to get its result while the hook manages the state.
  • Callbacks for notifying success and error

Installing

Using NPM:

npm i react-use-async-fn

Using yarn:

yarn add react-use-async-fn

Importing

const { useAsync, STATES } = require("react-use-async-fn");

or in ES6

import { useAsync, STATES } from "react-use-async-fn";

Usage:

Basic example:

  const [{ data, error, status}, trigger] = useAsync({
    fn: getData,
  });

You can provide your async function through the fn prop. The hook returns the state of the async function and a trigger. You can run you async function by calling the trigger. Any arguments provided to the trigger will be provided to your function.

If needed you can even await your function by using await on trigger.

const onClick = async () => {
  const result = await trigger(2);
  console.log({ result });
};

API

useAsync

This hook manages the state of execution of an async function

props:
fn: Async function to track and execute.
onDone: (Optional) Callback function called when the fn is ran successfully. It will be called with the result and the args provided to the fn.
onError: (Optional) Callback function called when the fnfailed with an error. It will be called with the error and the args provided to the fn.

returns:
Array of state, trigger.
[state, trigger]

state.data: The return value of the fn. Initially null.
state.status: Status of the function. One of [INITIAL, WORKING, DONE, FAILED]
state.error: The error thrown by the fn. Initially null.
state.isLoading: boolean. true if state.status is STATUS.WORKING.
trigger: Function to call the provided fn. All arguments are forwarded to the fn. You can await the trigger to get the output of fn.

useAbortableAsync(props)

This function manages the state of an async function which can be aborted.

The fn prop requires the last argument to be of AbortableLifecycle to use this hook.

props

fn: (...any[], { abortSignal: AbortSignal }) => Promise<any> Async function to track and execute.

Other props are same as useAsync.

returns

Array of state, actions
[state, { trigger, abort }]

state: same as [useAsync](#useAsync).
trigger: function which takes all arguments for fn, execpt the last argument AbortableLifecycle. The AbortableLifecycle argument is automatically injected by the hook.
abort: function to abort the request.

STATUSES

Enum of statuses

INITIAL: The status before triggering
WORKING: The status after triggering but before completion
DONE: The status when completed successfully
FAILED: The status when failed

AbortableLifecycle

The last argument of an AbortableAsyncFn. It has the shape of

  {
    abortSignal: AbortSignal,
  }

Examples:

useAsync:

import { useCallback } from 'react'
import { useAsync, STATUSES } from 'react-use-async-fn';

const sleep = () => new Promise(r => setTimeout(r, 5000))

function App() {
  const getData = useCallback(async (input: number) => {
    await sleep();
    return input + 1;
  }, []);

  const [{ data, error, status}, trigger] = useAsync({
    fn: getData,
  });

  return (
    <div>
      <h3>data</h3>
      <p>{data}</p>
      <h3>status</h3>
      <p>{status}</p>
      <h3>error</h3>
      <p>{error as string}</p>
      <button onClick={() => trigger(2)}>Trigger with 2</button>
    </div>
  )
}

useAbortableAsync

import { useCallback } from 'react'
import { AbortableLifecycle, STATUSES, useAbortableAsync } from 'react-use-async-fn';

function abortbleSleep(ms=5000, {abortSignal}: AbortableLifecycle): Promise<string>{
  return new Promise((resolve, reject) => {
    console.log("Promise Started");
    
    let timeout: ReturnType<typeof setTimeout>;
    
    const abortHandler = () => {
      clearTimeout(timeout);
      reject(new Error("Aborted"));
    }
    
    // start async operation
    timeout = setTimeout(() => {
      resolve("Promise Resolved");
      abortSignal?.removeEventListener("abort", abortHandler);
    }, ms);    
    
    abortSignal?.addEventListener("abort", abortHandler);
  });
}

function App() {
  const [{ data, error, status }, {trigger, abort}] = useAbortableAsync({
    fn: abortbleSleep,
  });

  return (
    <div>
      <h2>Abortable</h2>
      <h3>data</h3>
      <p>{data}</p>
      <h3>status</h3>
      <p>{status}</p>
      <h3>error</h3>
      <p>{(error as Error)?.message}</p>
      <p>
        <button onClick={() => trigger(5000)}>Trigger with 5000 ms</button>
      </p>
      <p>
        <button disabled={status != STATUSES.WORKING} onClick={() => abort()}>Abort</button>
      </p>
    </div>
  )
}

Package Sidebar

Install

npm i react-use-async-fn

Weekly Downloads

5

Version

0.2.0

License

MIT

Unpacked Size

80.7 kB

Total Files

25

Last publish

Collaborators

  • eskawl