This project is deprecated, please use https://github.com/pmndrs/suspend-react instead!
Dealing with async assets
Each asset you create comes with its own cache. When you request something from it, the arguments that you pass will act as cache-keys. If you request later on using the same keys, it won't have to re-fetch but serves the result that it already knows.
import React, { Suspense } from "react"
import { createAsset } from "use-asset"
// Create a cached source
const asset = createAsset(async (id, version) => {
// Any async task can run in here, fetch requests, parsing, workers, promises, ...
const res = await fetch(`https://hacker-news.firebaseio.com/${version}/item/${id}.json`)
return await res.json()
})
function Post({ id }) {
// Then read from it ...
const { by, title } = asset.read(id, "v0") // As many cache keys as you need
// By the time we're here the async data has resolved
return <div>{title} by {by}</div>
}
function App() {
<Suspense fallback={<div>loading...</div>}>
<Post id={10000} />
</Suspense>
}
Preloading assets
// You can preload assets, these will be executed and cached immediately
asset.preload("/image.png")
Cache busting strategies
// This asset will be removed from the cache in 15 seconds
const asset = createAsset(promiseFn, 15000)
// Clear all cached entries
asset.clear()
// Clear a specific entry
asset.clear("/image.png")
Peeking into entries outside of suspense
// This will either return the value (without suspense!) or undefined
asset.peek("/image.png")
Hooks and global cache
You can also use the useAsset
hook, which is modelled after react-promise-suspense. This makes it possible to define assets on the spot instead of having to define them externally. They use a global cache, anything you request at any time is written into it.
import { useAsset } from "use-asset"
function Post({ id }) {
const { by, title } = useAsset(async (id, version) => {
// Any async task can run in here, fetch requests, parsing, workers, promises, ...
const res = await fetch(`https://hacker-news.firebaseio.com/${version}/item/${id}.json`)
return await res.json()
}, id, "v0") // As many cache keys as you need
// By the time we're here the async data has resolved
return <div>{title} by {by}</div>
}
function App() {
<Suspense fallback={<div>loading...</div>}>
<Post id={1000} />
Cache busting, preload and peeking
The hook has the same API as any asset:
// Bust cache in 15 seconds
useAsset.lifespan = 15000
useAsset(promiseFn, "/image.png")
// Clear all cached entries
useAsset.clear()
// Clear a specific entry
useAsset.clear("/image.png")
// Preload entries
useAsset.preload(promiseFn, "/image.png")
// This will either return the value (without suspense!) or undefined
useAsset.peek("/image.png")
Recipes
Simple data fetching
Fetching posts from hacker-news: codesandbox
Infinite load on scroll
Fetching HN posts infinitely: codesandbox
Async dependencies
Component A waits for the result of component B: codesandbox