https://github.com/stegano/react-suspense-render-hook
React Suspense Render Hook: This hook allows you to declaratively define components that render when asynchronous data is processed.
https://github.com/stegano/react-suspense-render-hook
async indicator lazy-loading loading react render suspense use
Last synced: about 2 months ago
JSON representation
React Suspense Render Hook: This hook allows you to declaratively define components that render when asynchronous data is processed.
- Host: GitHub
- URL: https://github.com/stegano/react-suspense-render-hook
- Owner: stegano
- Created: 2023-09-03T14:32:04.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-01-08T14:38:50.000Z (over 1 year ago)
- Last Synced: 2025-04-24T00:49:24.099Z (about 2 months ago)
- Topics: async, indicator, lazy-loading, loading, react, render, suspense, use
- Language: TypeScript
- Homepage:
- Size: 135 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# React Suspense Render Hook

React Suspense Render Hook: This hook allows you to declaratively define components that render when asynchronous data is processed.
## Deprecated 🚀
This library has been updated to [`react-render-state-hook`](https://www.npmjs.com/package/react-render-state-hook), allowing for more reliable use of almost all the features. Please check the link below for further information.
- https://www.npmjs.com/package/react-render-state-hook## Installation
The easiest way to install [`react-suspense-render-hook`](https://www.npmjs.com/package/react-suspense-render-hook) is with [npm](https://www.npmjs.com/).
```bash
npm install react-suspense-render-hook
```Alternately, download the source.
```bash
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.```tsx
import { useState, useCallback } from "react";
import { useSuspenseRender } from "react-suspense-render-hook";const App = () => {
// Asynchronous task function
const asyncTask = useCallback(
() =>
new Promise((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();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) => (
Success({data})
Update
),
Loading..
,
(error) =>Error, Oops something went wrong.. :(, ({error.message})
,
);
};
```
Demo: https://stackblitz.com/edit/stackblitz-starters-pgefl6### SuspenseRenderProvider
The `SuspenseRenderProvider` allows for predefined loading or error components to be set externally.```tsx
import { useCallback, useEffect } from 'react';
import {
SuspenseRenderProvider,
useSuspenseRender,
} from 'react-suspense-render-hook';const Component = () => {
// Asynchronous task function
const asyncTask = useCallback(
() =>
new Promise((resolve) => {
setTimeout(resolve, 1000 * 1);
}),
[]
);const [suspenseRender, runAsyncTask] = useSuspenseRender();
useEffect(() => {
runAsyncTask(async () => {
await asyncTask();
});
}, []);// If not specified, components defined in `SuspenseRenderProvider` are used for `renderLoading` or `renderError`.
return suspenseRender(Success
);
};export const App = ({ children }) => {
return (
Loading..☀️}
renderError={Error!
}
>
);
};```
Demo: https://stackblitz.com/edit/stackblitz-starters-bwapyp## 🧐 Experimental features
### taskRunnerInterceptors
`taskRunnerInterceptors` can intercept `taskRunner` execution, allowing you to transform it. It can be useful for adding logs for data processing or injecting dummy data for use in Storybook and testing environments.```tsx
import { useCallback, useEffect } from 'react';
import {
SuspenseRenderProvider,
useSuspenseRender,
} from 'react-suspense-render-hook';const Component = () => {
// Asynchronous task function
const asyncTask = useCallback(async () => {
// e.g., return (await axios.get('.../data.json')).data.greeting;
return 'Hi';
}, []);const [suspenseRender, runAsyncTask] = useSuspenseRender();
useEffect(() => {
runAsyncTask(async () => {
const greeting = await asyncTask();
return greeting;
}, 'greeting');
}, []);return suspenseRender((greeting) =>
{greeting}
);
};export const App = ({ children }) => {
return (
Loading..☀️}
renderError={Error!
}
experimentals={{
taskRunnerInterceptors: [
async (_prevInterceptorResult, asyncTaskFunction, taskId) => {
if (taskId === 'greeting') {
return 'Hello';
}
return await asyncTaskFunction();
},
async (prevInterceptorResult, asyncTaskFunction, taskId) => {
if (taskId === 'greeting') {
// When `renderSuccess` is executed, it displays the text `Hello 😀`.
return `${prevInterceptorResult} 😀`;
}
return await asyncTaskFunction();
},
],
}}
>
);
};
```
Demo: https://stackblitz.com/edit/stackblitz-starters-4qxzui