Skip to content

v2.0.0

Choose a tag to compare

@stegano stegano released this 10 Nov 13:17
· 47 commits to main since this release

React Suspense Render Hook

NPM License NPM Downloads

React Suspense Render Hook: This hook allows you to declaratively define components that render when asynchronous data is processed.

Installation

The easiest way to install react-suspense-render-hook is with npm.

npm install react-suspense-render-hook

Alternately, download the source.

git clone https://github.com/stegano/react-suspense-render-hook.git

Quick Start

useSuspenseRender

The useSuspenseRender hook enables a declarative approach to display components based on asynchronous data processing status. Handle components' rendering based on data processing status within a single component.

import { useState, useCallback } from "react";
import { useSuspenseRender } from "react-suspense-render-hook";

const App = () => {
  // Asynchronous task function
  const asyncTask = useCallback(
    () =>
      new Promise<string>((resolve) => {
        const randomString = Math.random().toString(32).slice(2);
        setTimeout(() => resolve(randomString), 1000 * 3);
      }),
    [],
  );

  // You can use the `runAsyncTask` function to process asynchronous data again at your desired point after the screen has been rendered.
  const [suspenseRender, runAsyncTask] = useSuspenseRender<string, Error>();

  useEffect(() => {
    // Run asynchronous task function
    runAsyncTask(async () => {
      return asyncTask();
    });
  }, [asyncTask]);

  const handleButtonClick = useCallback(() => {
    // Run the `asyncTask` function
    runAsyncTask(async () => {
      return asyncTask();
    }); // Alternatively, you can use `runAsyncTask(new Promise(...))`;
  }, [asyncTask, runAsyncTask]);

  // Use `suspenseRender` to define rendering for data processing statuses: success, loading, or error. It auto-renders based on the `asyncTask` function's status.
  return suspenseRender(
    (data) => (
      <div>
        <p>Success({data})</p>
        <button type="button" onClick={handleButtonClick}>
          Update
        </button>
      </div>
    ),
    <p>Loading..</p>,
    (error) => <p>Error, Oops something went wrong.. :(, ({error.message})</p>,
  );
};

Demo: https://stackblitz.com/edit/stackblitz-starters-pgefl6

SuspenseRenderProvider

The SuspenseRenderProvider allows for predefined loading or error components to be set externally.

import { SuspenseRenderProvider, useSuspenseRender } from "react-suspense-render-hook";

const App = ({ children }) => {
  return (
    <SuspenseRenderProvider loading={<p>Loading..</p>} error={<p>Error!</p>}>
      <DataComponent />
    </SuspenseRenderProvider>
  )
}

// ...

const DataComponent = () => {
  const [ suspenseRender ] = useSuspenseRender(asyncTask);
  // If not specified, components defined in `SuspenseRenderProvider` are used for `loading` or `error`.
  return suspenseRender(
    <p>Success</p>
  );
}

Demo: https://stackblitz.com/edit/stackblitz-starters-bwapyp