https://github.com/crimx/use-suspensible
React hooks that can make any data suspensible.
https://github.com/crimx/use-suspensible
react react-hooks suspense
Last synced: 5 months ago
JSON representation
React hooks that can make any data suspensible.
- Host: GitHub
- URL: https://github.com/crimx/use-suspensible
- Owner: crimx
- License: mit
- Created: 2019-11-13T10:47:47.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2021-05-11T07:24:04.000Z (over 4 years ago)
- Last Synced: 2025-05-05T20:13:59.397Z (5 months ago)
- Topics: react, react-hooks, suspense
- Language: JavaScript
- Homepage:
- Size: 891 KB
- Stars: 12
- Watchers: 2
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# [use-suspensible](https://github.com/crimx/use-suspensible)
[](https://www.npmjs.com/package/use-suspensible)
[](https://travis-ci.com/crimx/use-suspensible)
[](https://coveralls.io/github/crimx/use-suspensible?branch=master)[](http://commitizen.github.io/cz-cli/)
[](https://conventionalcommits.org)
[](https://standardjs.com)
[](https://github.com/prettier/prettier)
React hooks that can make any data suspensible.
## Why?
This is a proof-of-concept for using Suspense with non-promise based async libraries.
Also see [observable-hooks](https://observable-hooks.js.org/guide/render-as-you-fetch-suspense.html) on implementing [Render-as-You-Fetch](https://reactjs.org/docs/concurrent-mode-suspense.html#approach-3-render-as-you-fetch-using-suspense) pattern with Suspense and Rxjs Observable.## Installation
yarn
```bash
yarn add use-suspensible
```npm
```bash
npm install --save use-suspensible
```## Usage
```jsx
import React, { Suspense, useState, useEffect } from 'react'
import { useSuspensible } from 'use-suspensible'function fetchData() {
return new Promise(resolve => {
setTimeout(() => {
resolve({ content: "content" })
}, 3000)
})
}const App = () => {
const [data, setData] = useState()
useEffect(
() => {
fetchData().then(setData)
},
[]
)return (
Loading...}>
)
}function Content({ data }) {
useSuspensible(data)
return (
{data.content}
);
}
```Default trigger Suspense on `null` or `undefined`.
```typescript
useSuspensible(data)
```Custom comparison for checking finish state.
```typescript
useSuspensible(data, data => data.status === 'finish')
```You can have any number of `useSuspensible` in a Component.
```jsx
useSuspensible(data1)
useSuspensible(data2)
useSuspensible(data3, data => data.status === 'finish')return (
<>
{data1.content}
{data2.content}
{data3.content}
>
)
```TypeScript >= 3.7
```typescript
interface StatePending {
status: 'pending'
value: null
}interface StateFinish {
status: 'finish'
value: number
}type States = StatePending | StateFinish
//....
useSuspensible(
data,
(data: States): data is StateFinish => data.status === 'finish'
)// Now data is of `StateFinish` type.
```## Beware
Due to the design of Suspense, each time a suspender is thrown, the children of `Suspense` Component will be destroyed and reloaded. Do not initialize async data and trigger Suspense in the same Component.
```jsx
import React, { Suspense, useState, useEffect } from 'react'
import { useSuspensible } from 'use-suspensible'function fetchData() {
return new Promise(resolve => {
setTimeout(() => {
resolve({ content: "content" })
}, 3000)
})
}const App = () => {
return (
Loading...}>
)
}function Content({ data }) {
const [data, setData] = useState()
// This will cause infinite update.
useEffect(
() => {
fetchData().then(setData)
},
[]
)
useSuspensible(data)
return (
{data.content}
);
}
```