Skip to main content

useCancelling()

Builds an Endpoint that cancels fetch everytime parameters change

Aborts inflight request if the parameters change.

Usage

npm install --save @data-client/hooks
export class Todo extends Entity {
  id = 0;
  userId = 0;
  title = '';
  completed = false;
  pk() {
    return `${this.id}`;
  }
  static key = 'Todo';
}
export const TodoResource = createResource({
  urlPrefix: 'https://jsonplaceholder.typicode.com',
  path: '/todos/:id',
  schema: Todo,
});
import { useSuspense } from '@data-client/react';
import { useCancelling } from '@data-client/hooks';
import { TodoResource } from './api/Todo';

export default function TodoDetail({ id }: { id: number }) {
  const todo = useSuspense(useCancelling(TodoResource.get, { id }), {
    id,
  });
  return <div>{todo.title}</div>;
}
import React from 'react';
import { AsyncBoundary } from '@data-client/react';
import TodoDetail from './TodoDetail';

function AbortDemo() {
  const [id, setId] = React.useState(1);
  return (
    <div>
      <AsyncBoundary fallback="...">
        <TodoDetail id={id} />
      </AsyncBoundary>
      <div>
        <button onClick={() => setId(id => Math.max(id - 1, 1))}>
          «
        </button>
        {id} &nbsp;
        <button onClick={() => setId(id => id + 1)}>»</button>
      </div>
    </div>
  );
}
render(<AbortDemo />);
🔴 Live Preview
Store

Try clicking the » very quickly. If you increment before it resolves the request will be cancelled and you should not see results in the store.

Warning

Be careful when using this with many disjoint components fetching the same arguments (Endpoint/params pair) to useSuspense(). This solution aborts fetches per-component, which means you might end up canceling a fetch that another component still cares about.

Types

function useCancelling<
E extends EndpointInterface & {
extend: (o: { signal?: AbortSignal }) => any;
},
>(endpoint: E, ...args: readonly [...Parameters<E>] | readonly [null]): E {

Part of @data-client/hooks