Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/f/react-wait

Complex Loader Management Hook for React Applications
https://github.com/f/react-wait

hooks loading react react-hooks ui-components ux

Last synced: 4 days ago
JSON representation

Complex Loader Management Hook for React Applications

Awesome Lists containing this project

README

        





Complex Loader Management Hook for React.


Read the Medium post "Managing Complex Waiting Experiences on Web UIs".



[![npm version](https://badge.fury.io/js/react-wait.svg)](https://badge.fury.io/js/react-wait)
[![build](https://api.travis-ci.org/f/react-wait.svg?branch=master)](https://travis-ci.org/f/react-wait)
[![codecov](https://codecov.io/gh/f/react-wait/branch/master/graph/badge.svg)](https://codecov.io/gh/f/react-wait)

---

[![Edit useWait](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/y3w5v5lk0j)

**react-wait** is a **React Hook** helps to manage multiple loading states on the page without any conflict. It's based on a **very simple idea** that manages an **`Array`** of multiple loading states. The **built-in loader component** listens its registered loader and immediately become loading state.

## **Why not `React.Suspense`?**:

React has its own Suspense feature to manage all the async works. For now it only supports code-splitting (not data-fetching).

`useWait` allows you to manage waiting experiences much more explicitly and **not only for Promised/async patterns but also complete loading management**.

# Overview

Here's a quick overview that what's `useWait` for:

```jsx
import { useWait, Waiter } from "react-wait";

function A() {
const { isWaiting } = useWait();
return (


{isWaiting("creating user") ? "Creating User..." : "Nothing happens"}

);
}

function B() {
const { anyWaiting } = useWait();
return (


{anyWaiting() ? "Something happening on app..." : "Nothing happens"}

);
}

function C() {
const { startWaiting, endWaiting, isWaiting } = useWait();

function createUser() {
startWaiting("creating user");
// Faking the async work:
setTimeout(() => {
endWaiting("creating user");
}, 1000);
}

return (

}>
Create User


);
}

ReactDOM.render(


,
document.getElementById("root")
);
```

# Quick Start

If you are a **try and learn** developer, you can start trying the **react-wait** now using [codesandbox.io](https://codesandbox.io).

[Quick start on CodeSandbox](https://codesandbox.io/s/y3w5v5lk0j)

### 1. Install:

```bash
yarn add react-wait
```

### 2. Require:

```jsx
import { Waiter, useWait } from "react-wait";

function UserCreateButton() {
const { startWaiting, endWaiting, isWaiting, Wait } = useWait();

return (
startWaiting("creating user")}
disabled={isWaiting("creating user")}
>
Creating user!}>
Create User


);
}
```

### 3. Wrap with the `Waiter` Context Provider

And you should wrap your `App` with `Waiter` component. It's actually a `Context.Provider` that provides a loading context to the component tree.

```jsx
const rootElement = document.getElementById("root");
ReactDOM.render(


,
rootElement
);
```

## Installation

```bash
$ yarn add react-wait
# or if you using npm
$ npm install react-wait
```

## The API

**react-wait** provides some helpers to you to use in your templates.

#### `anyWaiting()`

Returns boolean value if any loader exists in context.

```jsx
const { anyWaiting } = useWait();

return Disabled while waiting;
```

#### `isWaiting(waiter String)`

Returns boolean value if given loader exists in context.

```jsx
const { isWaiting } = useWait();

return (

Disabled while creating user

);
```

#### `startWaiting(waiter String)`

Starts the given waiter.

```jsx
const { startWaiting } = useWait();

return startWaiting("message")}>Start;
```

#### `endWaiting(waiter String)`

Stops the given waiter.

```jsx
const { end } = useWait();

return endWaiting("message")}>Stop;
```

## Using `Wait` Component

```jsx
function Component() {
const { Wait } = useWait();
return (
Waiting...}>
The content after waiting done

);
}
```

Better example for a `button` with loading state:

```jsx

Creating User...}>
Create User

```

## Making Reusable Loader Components

With reusable loader components, you will be able to use custom loader components as example below. This will allow you to create better **user loading experience**.

```jsx
function Spinner() {
return ;
}
```

Now you can use your spinner everywhere using `waiting` attribute:

```jsx

}>
Create User

```

## Creating Waiting Contexts using `createWaitingContext(context String)`

To keep your code DRY you can create a `Waiting Context` using `createWaitingContext`.

```jsx
function CreateUserButton() {
const { createWaitingContext } = useWait();

// All methods will be curried with "creating user" on.
const { startWaiting, endWaiting, isWaiting, Wait } = createWaitingContext(
"creating user"
);

function createUser() {
startWaiting();
setTimeout(endWaiting, 1000);
}

return (

Create User

);
}
```

## Contributors

- Fatih Kadir Akın, (creator)

## Other Implementations

Since **react-wait** based on a very simple idea, it can be implemented on other frameworks.

- [vue-wait](https://github.com/f/vue-wait): Multiple Process Loader Management for Vue.
- [dom-wait](https://github.com/f/dom-wait): Multiple Process Loader Management for vanilla JavaScript.

## License

MIT © [Fatih Kadir Akın](https://github.com/f)