Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

use-suspensible

0.2.3 • Public • Published

use-suspensible

npm-version Build Status Coverage Status

Commitizen friendly Conventional Commits JavaScript Style Guide code style: prettier

use-suspensible

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 on implementing Render-as-You-Fetch pattern with Suspense and Rxjs Observable.

Installation

yarn

yarn add use-suspensible

npm

npm install --save use-suspensible

Usage

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 (
    <Suspense fallback={<h1>Loading...</h1>}>
      <Content data={data} />
    </Suspense>
  )
}
 
function Content({ data }) {
  useSuspensible(data)
  return (
    <h1>{data.content}</h1>
  );
}

Default trigger Suspense on null or undefined.

useSuspensible(data)

Custom comparison for checking finish state.

useSuspensible(data, data => data.status === 'finish')

You can have any number of useSuspensible in a Component.

useSuspensible(data1)
useSuspensible(data2)
useSuspensible(data3, data => data.status === 'finish')
 
return (
  <>
    <h1>{data1.content}</h1>
    <h1>{data2.content}</h1>
    <h1>{data3.content}</h1>
  </>
)

TypeScript >= 3.7

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.

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 (
    <Suspense fallback={<h1>Loading...</h1>}>
      <Content />
    </Suspense>
  )
}
 
function Content({ data }) {
  const [data, setData] = useState()
  // This will cause infinite update.
  useEffect(
    () => {
      fetchData().then(setData)
    },
    []
  )
  useSuspensible(data)
  return (
    <h1>{data.content}</h1>
  );
}

Install

npm i use-suspensible

DownloadsWeekly Downloads

2

Version

0.2.3

License

MIT

Unpacked Size

12.1 kB

Total Files

16

Last publish

Collaborators

  • avatar