Skip to main content

useDLE() - [D]ata [L]oading [E]rror

function useDLE(
endpoint: ReadEndpoint,
...args: Parameters<typeof endpoint> | [null]
): {
data: Denormalize<typeof endpoint.schema>;
loading: boolean;
error: Error | undefined;
};

In case you cannot use suspense, useDLE() is just like useSuspense() but returns [D]ata [L]oading [E]rror values.

Expiry StatusFetchDataLoadingErrorConditions
Invalidyes1undefinedtruefalsenot in store, deletion, invalidation, invalidIfStale
Staleyes1denormalizedfalsefalse(first-render, arg change) & expiry < now
Validnodenormalizedfalsemaybe2fetch completion
noundefinedfalsefalsenull used as second argument
note
  1. Identical fetches are automatically deduplicated
  2. Hard errors to be caught by Error Boundaries
Conditional Dependencies

Use null as the second argument on any rest hooks to indicate "do nothing."

// todo could be undefined if id is undefined
const todo = useDLE(TodoResource.get, id ? { id } : null);

Hook usage

Fixtures
GET /profiles
[{"id":"1","fullName":"Einstein","bio":"Smart physicist"},{"id":"2","fullName":"Elon Musk","bio":"CEO of Tesla, SpaceX and owner of Twitter"}]
api/Profile.ts
import { Entity, createResource } from '@rest-hooks/rest';
export class Profile extends Entity {
readonly id: number | undefined = undefined;
readonly img: string = '';
readonly fullName: string = '';
readonly bio: string = '';
pk() {
return this.id?.toString();
}
}
export const ProfileResource = createResource({
path: '/profiles/:id',
schema: Profile,
});
ProfileList.tsx
import { useDLE } from '@rest-hooks/react';
import { ProfileResource } from './api/Profile';
function ProfileList(): JSX.Element {
const { data, loading, error } = useDLE(ProfileResource.getList);
if (error) return <div>Error {error.status}</div>;
if (loading || !data) return <>loading...</>;
return (
<div>
{data.map(profile => (
<div key={profile.pk()}>
<h4>{profile.fullName}</h4>
<p>{profile.bio}</p>
</div>
))}
</div>
);
}
render(<ProfileList />);
Live Preview
Loading...
Store