Skip to content

Commit

Permalink
docs: update about useAbortableEffect
Browse files Browse the repository at this point in the history
  • Loading branch information
SukkaW committed Mar 8, 2024
1 parent f4f4b58 commit 6dc52bd
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
28 changes: 27 additions & 1 deletion docs/src/pages/best-practice.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ const ExampleComponent = ({ dataKey }: ExampleComponentProps) => {
Here, although the request for `data1` happened before `data2`, the response for `data2` is received before `data1`. And `useIsMountedRef` doesn't help with that.

To properly avoid `setData(data1)` from being called, the correct pattern is described below.
You can also use [`useAbortableEffect`](./use-abortable-effect) instead.

```tsx
interface ExampleComponentProps {
Expand Down Expand Up @@ -156,3 +155,30 @@ const ExampleComponent = ({ dataKey }: ExampleComponentProps) => {
│ Request data 2 ────► data2 response (setData(data2)) │
| isCancelled: false | isCancelled: false, setData(data2)
```

You can also use [`useAbortableEffect`](./use-abortable-effect) to achieve the same thing with less boilerplate code:

```tsx
interface ExampleComponentProps {
dataKey: 'data1' | 'data2'
}

const ExampleComponent = ({ dataKey }: ExampleComponentProps) => {
const [data, setData] = useState(null);

// Do notice that useAbortableEffect requires AbortController support
useAbortableEffect((signal) => {
someAsyncStuff().then(data => {
if (signal.aborted) return
setData(data);
});
}, [dataKey]);
}
```

```
│ Request data 1 ───────────────────────────────────────────────────────► data1 response │
| aborted: false | aborted | aborted, no setData(data1)
│ Request data 2 ────► data2 response (setData(data2)) │
| aborted: false | aborted: false, setData(data2)
```
16 changes: 16 additions & 0 deletions docs/src/pages/use-abortable-effect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ useAbortableEffect((signal) => {
}, [dataKey]);
```

You can also pass the `signal` to your async function if it supports `AbortSignal`:

```tsx
useAbortableEffect((signal) => {
someAsyncStuff({ signal })
.then(data => {
if (!signal.aborted) return
setData(data);
})
.catch(error => {
if (error.name === 'AbortError') return
setError(error);
});
}, [dataKey]);
```

Note that [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) requires extra configuration in order to check dependency array for third-party hooks:

```json filename=".eslintrc.json" copy
Expand Down

0 comments on commit 6dc52bd

Please sign in to comment.