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-wait

v0.3.0

Published

Complex Loader Management for React Applications

Downloads

75,126

Readme

npm version build


Play with Demo.

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 a Arrayg with 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:

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

function A() {
  const { isWaiting } = useWait();
  return (
    <div>
      {isWaiting("creating user") ? "Creating User..." : "Nothing happens"}
    </div>
  );
}

function B() {
  const { anyWaiting } = useWait();
  return (
    <div>
      {anyWaiting() ? "Something happening on app..." : "Nothing happens"}
    </div>
  );
}

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

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

  return (
    <button disabled={isWaiting("creating user")} onClick={createUser}>
      <Wait on="creating user" fallback={<Spinner />}>
        Create User
      </Wait>
    </button>
  );
}

ReactDOM.render(
  <Waiter>
    <C />
  </Waiter>,
  document.getElementById("root")
);

Quick Start

If you are a try and learn developer, you can start trying the react-wait now using codesandbox.io.

Edit useWait

1. Install:

yarn add react-wait

2. Require:

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

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

  return (
    <button
      onClick={() => startWaiting("creating user")}
      disabled={isWaiting("creating user")}
    >
      <Wait on="creating user" fallback={<div>Creating user!</div>}>
        Create User
      </Wait>
    </button>
  );
}

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.

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Waiter>
    <App />
  </Waiter>,
  rootElement
);

Installation

$ 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.

const { anyWaiting } = useWait();

return <button disabled={anyWaiting()}>Disabled while waiting</button>;

isWaiting(waiter String)

Returns boolean value if given loader exists in context.

const { isWaiting } = useWait();

return (
  <button disabled={isWaiting("creating user")}>
    Disabled while creating user
  </button>
);

startWaiting(waiter String)

Starts the given waiter.

const { startWaiting } = useWait();

return <button onClick={() => startWaiting("message")}>Start</button>;

endWaiting(waiter String)

Stops the given waiter.

const { end } = useWait();

return <button onClick={() => endWaiting("message")}>Stop</button>;

Using Wait Component

function Component() {
  const { Wait } = useWait();
  return (
    <Wait on="the waiting message" fallback={<div>Waiting...</div>}>
      The content after waiting done
    </Wait>
  );
}

Better example for a button with loading state:

<button disabled={isWaiting("creating user")}>
  <Wait on="creating user" fallback={<div>Creating User...</div>}>
    Create User
  </Wait>
</button>

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.

function Spinner() {
  return <img src="spinner.gif" />;
}

Now you can use your spinner everywhere using waiting attribute:

<button disabled={isWaiting("creating user")}>
  <Wait on="creating user" fallback={<Spinner />}>
    Create User
  </Wait>
</button>

Creating Waiting Contexts using createWaitingContext(context String)

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

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 (
    <Button disabled={isWaiting()} onClick={createUser}>
      <Wait fallback="Creating User...">Create User</Wait>
    </Button>
  );
}

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: Multiple Process Loader Management for Vue.
  • dom-wait: Multiple Process Loader Management for vanilla JavaScript.

License

MIT © Fatih Kadir Akın