# react-use-promise-raii

> React hooks that track in-flight promises with a global counter, RAII style — for global loading indicators and input blocking

Latest version **1.1.0** (published 2026-07-04) · MIT license · 0 weekly downloads

## Install

```sh
npm install react-use-promise-raii
pnpm add react-use-promise-raii
yarn add react-use-promise-raii
bun add react-use-promise-raii
```

## Health

**Score 60/100 (C)** — status: active.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.1.0 |
| Published | 2026-07-04 |
| First published | 2024-01-21 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=14 |
| Dependencies | 0 |
| Unpacked size | 21.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | eezz4 |
| Maintainers | eezz4 |
| Keywords | react, hooks, promise, loading, spinner, pending, raii, blocking |

## Links

- npm: https://www.npmjs.com/package/react-use-promise-raii
- Repository: https://github.com/eezz4/react-use-promise-raii
- Homepage: https://github.com/eezz4/react-use-promise-raii#readme
- Issues: https://github.com/eezz4/react-use-promise-raii/issues
- npm.io page: https://npm.io/package/react-use-promise-raii

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 1.1.0 (latest) — 2026-07-04
- 1.0.2 — 2024-01-21

## README

# react-use-promise-raii

[![NPM](https://img.shields.io/npm/v/react-use-promise-raii.svg)](https://www.npmjs.com/package/react-use-promise-raii) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)

React hooks that track in-flight promises with a shared counter, RAII style.
Wrap a promise and the counter is incremented while it is pending and always
decremented when it settles (resolve or reject) — useful for global loading
overlays and input blocking.

Requires React 18 or 19.

## Install

```bash
npm install --save react-use-promise-raii
```

## API

| Export | Description |
| --- | --- |
| `ProviderPromiseRaii` | Context provider that owns the pending counter. |
| `useCheckPromiseRaii()` | Returns the current number of pending wrapped promises. |
| `usePromiseRaii()` | Returns `wrap(promise)` — counts the promise while pending. |
| `usePromiseRaiiSleep()` | Returns `wrap(promise, ms = 100)` — like `usePromiseRaii`, but holds the counter for at least `ms` (prevents spinner flicker). |
| `usePromiseRaiiArray()` | Returns `wrap(promises[])` — counts a whole `Promise.all` batch as one acquisition. |

Without a `ProviderPromiseRaii` ancestor, the wrap hooks are no-ops and
`useCheckPromiseRaii` always returns `0`.

## Usage

#### global blocking io : example1 + example2 + example3

- example1: provider installation is required.
```tsx
import { ProviderPromiseRaii } from "react-use-promise-raii";

export default function App() {
  return (
    <>
      <GlobalStyle />
      <ProviderPromiseRaii>
        <HomePage/>
      </ProviderPromiseRaii>
    </>
  );
}
```

- example2: When you need global blocking...
```tsx
import { useCheckPromiseRaii } from "react-use-promise-raii";

const useBlockingIoPreventKeyEvents = (isBlocking: boolean) => {
  useEffect(() => {
    if (!isBlocking) return;
    const keyEvents = ["keydown", "keypress", "keyup"];
    const onKeyEvent = (e: Event) => e.preventDefault();
    keyEvents.forEach((k) => document.addEventListener(k, onKeyEvent));
    return () => {
      keyEvents.forEach((k) => document.removeEventListener(k, onKeyEvent));
    };
  }, [isBlocking]);
};

export const BlockingIo = () => {
  const isBlocking = useCheckPromiseRaii() > 0; // useCheckPromiseRaii

  useBlockingIoPreventKeyEvents(isBlocking);

  return (
    <WrBlockingIo isBlocking={isBlocking}>
      <Watch visible={isBlocking} color={"#ffffff"} width={80} height={80} />
    </WrBlockingIo>
  );
};

const WrBlockingIo = styled.div<{ isBlocking: boolean }>`
  visibility: ${(props) => (props.isBlocking ? "visible" : "hidden")};

  z-index: ${zIndex.blocking};
  position: fixed;
  width: 100%;
  height: 100%;

  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
`;
```

- example3: When you want to delay a promise.
```ts
import { usePromiseRaiiSleep } from "react-use-promise-raii";

export const useAxios = () => {
  const raiiSleep = usePromiseRaiiSleep();

  const axiosGet = useCallback(
    async (queryKey: string) => {
      if (queryKey.length === 0) return null;
      const { data } = await raiiSleep(axios.get(queryKey, axiosConfig), 1000);
      return data;
    },
    [raiiSleep]
  );

  // ...

  return {axiosGet, ... }
}
```

## License

MIT © [eezz4](https://github.com/eezz4)

---
_Source: https://npm.io/package/react-use-promise-raii · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
