Skip to content

A simple React hook that provides state for async actions.

License

Notifications You must be signed in to change notification settings

stefee/react-promise-state-hook

Repository files navigation

react-promise-state-hook

The usePromiseState hook provides you with React state for a Promise returned from an async function, including its status (NOT_STARTED, PENDING, FULFILLED or REJECTED) and its resolved or rejected value. The API is heavily inspired by Apollo GraphQL useQuery hook.

Install:

npm install react-promise-state-hook

Alternatively, you may copy the source code directly into your project as this library is published under the Unlicense license.

Usage example:

import * as React from "react";
import {usePromiseState, PromiseStatus} from "react-promise-state-hook";

const MyApp = () => {
  const [fetchCustomer, fetchCustomerState] = usePromiseState(
    React.useCallback(async () => {
      // Do asynchronous stuff here.
    }, []),
  );

  if (fetchCustomerState.status === PromiseStatus.FULFILLED) {
    return <Customer data={fetchCustomerState.value} />;
  }

  return (
    <div>
      <button
        onClick={fetchCustomer}
        disabled={fetchCustomerState.status === PromiseStatus.PENDING}
      >
        Start
      </button>
      {fetchCustomerState.status === PromiseStatus.REJECTED && (
        <div>Error: {fetchCustomerState.err.message}</div>
      )}
    </div>
  );
};

Options

By default, any errors thrown by an async callback will be caught and logged using console.error.

The createUsePromiseState function allows you to set a custom onError handler:

import {createUsePromiseState} from "react-promise-state-hook";

const handleError = (error: unknown) => {
  // Do error reporting here.
};

export const usePromiseState = createUsePromiseState({onError: handleError});
const [fetchCustomer, fetchCustomerState] = usePromiseState(
  React.useCallback(async () => {
    // Do asynchronous stuff here.
  }, []),
);

You can override the onError handler when calling usePromiseState:

const [fetchCustomer, fetchCustomerState] = usePromiseState(
  React.useCallback(async () => {
    // Do asynchronous stuff here.
  }, []),
  {
    onError: React.useCallback((error: unknown) => {
      // Do error reporting here.
    }, []),
  },
);