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-promise-container

v0.2.6

Published

PromiseContainer is a higher-order component to run a single or multiple promises, before rendering a component.

Downloads

13

Readme

react-promise-container Build Status Greenkeeper badge

PromiseContainer is a higher-order component to run a single or multiple promises, before rendering a component.

Installation

npm install react-promise-container --save

Usage

To wrap your component with some promises, do something like this:

import promiseContainer from 'react-promise-container';
import {getUser} from './some-file-with-api-calls';
import ExampleComponent from './ExampleComponent';

function mapPromisesToProps() {
  return {
    user: getUser(),
  }
}

export default promiseContainer(mapPromisesToProps)(ExampleComponent);

You can define as many promises as you want and use the props that are given from higher up:

import promiseContainer from 'react-promise-container';
import {getUser, getArticle} from './some-file-with-api-calls';
import ExampleComponent from './ExampleComponent';

function mapPromisesToProps(ownProps) {
  return {
    user: getUser(),
    article: getArticle(ownProps.articleId),
  }
}

export default promiseContainer(mapPromisesToProps)(ExampleComponent);

When all promises are fulfilled

As soon as all promises are fulfilled, ExampleComponent will be rendered. The results of the promises will be passed as props called user and article:

class ExampleComponent extends React.Component {
  render() {
    const {user, article} = this.props;
    return <div>
      <p>{article.title}</p>
      <p>{article.body}</p>
      <p>Posted by {user.name}</p>
    </div>
  }
}

Note that you don't have to handle any loading state inside of your presentational component. That's because this component is only rendered after all promises are fulfilled.

While promises are pending

To render something while pending, pass it as a second component:

promiseContainer(mapPromisesToProps)(
  ExampleComponent,
  LoadingComponent,
);

or something like:

promiseContainer(mapPromisesToProps)(
  ExampleComponent,
  () => <p>One moment please...</p>,
);

When a promise fails

To render something else when something went wrong, pass it as the third component:

promiseContainer(mapPromisesToProps)(
  ExampleComponent,
  LoadingComponent,
  ErrorComponent,
);

or something like:

promiseContainer(mapPromisesToProps)(
  ExampleComponent,
  () => <p>One moment please...</p>,
  error => <p>{error.message}</p>,
);

Updating promises

At some point, you'd probably want the result of a promise to be updated. For example, when you want to edit an article that you've fetched before. There are a couple of ways to do this:

props.promiseContainer.refresh()

This function is passed to your component and it will rerun all promises that were given. After fulfilling the promises again, the new result will be passed by the same props. At this moment, this will not change to a pending state in the process.

props.promiseContainer.mutate(mutationPromise, expectedResult)

You can use this function to implement optimistic UI. You pass it a promise (for example, to make a request to an API) and a function to describe what the expected result for this mutation is. For example, this is how you could implement a like button:

const {addLike, removeLike, isLiking} from './like-api';

class LikeButton extends React.Component {
  render() {
    return <button onClick={e => this.toggle(e)}>
      {this.props.isLiking ? 'unlike' : 'like'}
    </button>;
  }

  toggle(e) {
    const {mutate, refresh} = this.props.promiseContainer;
    const saveFn = () => this.props.isLiking ? addLike() : removeLike();
    mutate(saveFn, previousResult => {
      return { isLiking: !previousResult.isLiking };
    }).then(refresh);
  }
}

function mapPromisesToProps() {
  return {
    isLiking: isLiking(),
  };
}

export default promiseContainer(mapPromisesToProps)(LikeButton);

This will update the result of isLiking immediately, even before the request to save its new state is started. After the request of the mutation is done, the actual truth will be refetched. If the mutation fails, it will revert to the original result. Based on this excellent article, something like this should never take more than 2 seconds, so this promise will fail if it takes more than that.