# Aborting Fetch

[AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) provides a new way of cancelling
fetches that are no longer considered relevant. This can be hooked into fetch via the second `RequestInit` parameter.

## Cancelling on params change

Sometimes a user has the opportunity to fill out a field that is used to affect the results of a network call.
If this is a text input, they could potentially type quite quickly, thus creating a lot of network requests.

Using [useCancelling()](https://dataclient.io/docs/api/useCancelling.md) will automatically cancel in-flight requests if the parameters
change before the request is resolved.

```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.
