npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-use-async-fn

v0.2.0

Published

React hook for managing the state of an async function

Downloads

40

Readme

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>
  )
}