react-loading-hoc

React higher-order component that abstracts out loading state to a component prop

Usage no npm install needed!

<script type="module">
  import reactLoadingHoc from 'https://cdn.skypack.dev/react-loading-hoc';
</script>

README

react-loading-hoc

Build Status Coverage Status

react-loading-hoc is a React higher-order component that abstracts out the loading state of a component to an isLoading prop.

The intended use case is for frontend designs that have a dedicated loading UI for long-running asynchronous actions. This HOC abstracts out the need to manually setState on the component; instead, you invoke a prop on the component with a done callback, which, when called, changes the value of isLoading passed to the wrapped child component.

API

this.props.loading and this.props.isLoading

Each wrapped child component receives the following as props:

  • isLoading: True or false, depending on whether the component is currently in a loading state.
  • loading: A function to be called with a single-parameter function as input. Calling loading will set isLoading to true, and invoking the callback parameter on its input function will set isLoading to false.

In the below example, the component's isLoading prop is true when the network request is in-flight. In practice, Loading... is displayed while the component is loading, and Done! displays at all other times.

import React from 'react';
import request from 'browser-request';
import HOC from 'react-loading-hoc';

/**
 * Example usage of the HOC for a client-side AJAX request.
 */
class NetworkRequest extends React.Component {
  doNetworkRequest(evt) {
    evt.preventDefault();

    // The HOC adds a `loading` prop to the wrapped component, intended to be invoked as a function
    // to set the current loading state of the component. The parameter provided to `loading` should
    // be a single-argument callback function that invokes the callback parameter when the work is
    // complete, e.g. when the component is no longer in a loading state.
    // In the below example, the `loading` function is invoked at the beginning of the network
    // request, and the callback parameter `done` is invoked when the network request is complete.
    this.props.loading((done) => request.post('/slow', done));
  }

  render() {
    // The HOC passes an `isLoading` prop to the wrapped component to indicate whether the component
    // is in a loading state, as determined by invocations of the `loading` prop function described
    // above. Changes to the boolean value of this prop (as performed by the higher-order component)
    // will cause React to appropriately re-render this component.
    const {isLoading} = this.props;

    return (
      <div>
        <button onClick={this.doNetworkRequest.bind(this)}>
          Start async network request
        </button>
        {isLoading ? 'Loading...' : 'Done!'}
      </div>
    );
  }
}

export default HOC(NetworkRequest);

Accessing the wrapped component

The wrapped component is accessible via a ref by the property component. For example, accessing a method defined on a component wrapped in the HOC can be done as follows:

import React from 'react';
import HOC from 'react-loading-hoc';

class Wrapped extends React.Component {
  someMethod() {
    return 'text';
  }

  render() {
    ...
  }
}

const hoc = HOC(Wrapped);
console.log(hoc.component.someMethod());  // 'text'

Examples

Use case examples are available in the examples/ directory. To run it locally,

$ git clone ...
$ npm install
$ npm run build-example
$ npm run start
# Starts a server at http://localhost:4700 serving example/index.html