# useCancelling()

Builds an Endpoint that cancels fetch everytime parameters change

[Aborts](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) inflight request if the parameters change.

## Usage

```tsx title="resources/Todo"
import { Entity, resource } from '@data-client/rest';

export class Todo extends Entity {
  id = 0;
  userId = 0;
  title = '';
  completed = false;

  static key = 'Todo';
}
export const TodoResource = resource({
  urlPrefix: 'https://jsonplaceholder.typicode.com',
  path: '/todos/:id',
  schema: Todo,
});
```

```tsx title="TodoDetail" {5}
import { useSuspense, useCancelling } from '@data-client/react';
import { TodoResource } from './resources/Todo';

export default function TodoDetail({ id }: { id: number }) {
  const todo = useSuspense(useCancelling(TodoResource.get, { id }), {
    id,
  });
  return <div>{todo.title}</div>;
}
```

```tsx title="Demo"
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 />);
```

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: 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

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