react-use-resource
Version:
Convert a promise returning function into a suspense compatible resource.
95 lines (68 loc) • 2.98 kB
Markdown
<h1 align="center">react-use-resource</h1>
Convert a promise returning function into a suspense compatible resource.
[](https://github.com/feerzlay/react-use-resource/blob/master/LICENSE)
[](https://www.npmjs.com/package/react-use-resource)
[](https://www.npmjs.com/package/react-use-resource)
[](https://isitmaintained.com/project/feerzlay/react-use-resource)
## Installation
```bash
npm install react-use-resource
```
```bash
yarn add react-use-resource
```
## Usage
Wrap an application into a `ResourcesBoundary` component. All request results will be cached in there.
```tsx
import { Suspense } from 'react';
import { ResourcesBoundary } from 'react-use-resource';
export function Application() {
return (
<ResourcesBoundary>
<Suspense fallback="Loading...">
<User />
</Suspense>
</ResourcesBoundary>
);
}
```
Declare a promise returning function in any convenient way.
```ts
interface IUser {
username: string;
}
export function getUser(id: number) {
return fetch(`.../users/${id}`).then(response => response.json<IUser>());
}
```
The `useResource` hook takes a resource id, a promise returning function and a dependency list (which works simmilar to `useEffect` hook) and returns a resource for a provided function. Returned resource has `read` and `refresh` methods.
```tsx
import { useResource } from 'react-use-resource';
export function User() {
const resource = useResource('USER', getUser, [42]);
return (
<h1>{ resource.read().username }<h1>
);
};
```
Resource id should be unique for a rendered component tree. Variables from a dependency list are passed down to a function as an arguments. Cached resource is invalidated upon a component unmount.
### Request cancellation
Ideally, upon a dependency list change we want to cancel a previous outgoing request. In order to achieve this our function should return not a simple promise but a tuple of a promise and a cancellation function.
```ts
export function getUser(id: number): [Promise<IUser>, () => void] {
const controller = new AbortController();
const signal = controller.signal;
const promise = fetch(`.../users/${id}`, { signal }).then(response => response.json<IUser>());
return [promise, controller.abort];
}
```
### Lazy resources
Instead of `useResource` we can use `useLazyResource` hook. This way the resource will be requested only upon the `read` or `refresh` call.
### SSR
We can pass a `cache` property to `ResourcesBoundary`. All data will be written to and read from this record.
```tsx
const cache: Record<string, any> = {};
<ResourcesBoundary cache={cache}>
<Application />
</ResourcesBoundary>
```