{"id":19686331,"url":"https://github.com/closeio/use-abortable-effect","last_synced_at":"2025-04-29T06:31:24.205Z","repository":{"id":39085281,"uuid":"273182174","full_name":"closeio/use-abortable-effect","owner":"closeio","description":" Super simple React hook for running abortable effects based on the AbortController API.","archived":false,"fork":false,"pushed_at":"2023-01-06T09:17:09.000Z","size":1769,"stargazers_count":12,"open_issues_count":19,"forks_count":0,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-04-05T13:51:24.345Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://closeio.github.io/use-abortable-effect/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/closeio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-18T08:22:57.000Z","updated_at":"2024-03-13T16:46:21.000Z","dependencies_parsed_at":"2023-02-05T18:45:44.691Z","dependency_job_id":null,"html_url":"https://github.com/closeio/use-abortable-effect","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/closeio%2Fuse-abortable-effect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/closeio%2Fuse-abortable-effect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/closeio%2Fuse-abortable-effect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/closeio%2Fuse-abortable-effect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/closeio","download_url":"https://codeload.github.com/closeio/use-abortable-effect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251450656,"owners_count":21591407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T18:27:33.125Z","updated_at":"2025-04-29T06:31:21.973Z","avatar_url":"https://github.com/closeio.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# use-abortable-effect\n\n[![NPM](https://img.shields.io/npm/v/@closeio/use-abortable-effect.svg)](https://www.npmjs.com/package/@closeio/use-abortable-effect) [![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-success)](https://prettier.io)\n\nSuper simple React hook for running abortable effects based on the [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) API.\n\n[Check the live DEMO](https://closeio.github.io/use-abortable-effect/).\n\n### \u003cimg height=\"40px\" src=\"./close.svg\" /\u003e\n\nInterested in working on projects like this? [Close](https://close.com) is looking for [great engineers](https://jobs.close.com) to join our team!\n\n## Install\n\n```bash\nyarn add @closeio/use-abortable-effect\n```\n\n## Benefits\n\n- Extremely lightweight (less than 500B minzipped).\n- It uses the [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) API and it is compatible with the [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) API.\n- If a browser does not support the [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) API then the hook behaves exactly like a regular [`useEffect`](https://reactjs.org/docs/hooks-effect.html) hook. See [Can I Use](https://caniuse.com/#search=abortcontroller) for browser support overview.\n- No other 3rd-party dependencies.\n\n## API differences over [`useEffect`](https://reactjs.org/docs/hooks-effect.html)\n\n- API is compatible with [`useEffect`](https://reactjs.org/docs/hooks-effect.html),\n  where the effect function you pass-in accepts an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) instance as a param and you\n  can return a cleanup function that accepts an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) instance.\n- Supports abortable [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) requests.\n- Supports running custom operations/computations that can be easily aborted.\n- Auto-aborts effects on re-run (or component unmount), unless you provide\n  a custom cleanup function.\n\n```jsx\nuseEffect(() =\u003e {\n  // do something\n\n  return () =\u003e {\n    /* cleanup */\n  };\n}, [deps]);\n\nconst abortControllerRef = useAbortableEffect(\n  (abortSignal) =\u003e {\n    // do something\n\n    return (abortController) =\u003e {\n      /* do cleanup, you should probably abort */\n    };\n  },\n  [deps],\n);\n```\n\n## Usage\n\n### Abortable [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) requests\n\n```jsx\nimport React from 'react';\nimport useAbortableEffect from '@closeio/use-abortable-effect';\n\nexport default function MyAbortableFetchComponent() {\n  const abortControllerRef = useAbortableEffect((abortSignal) =\u003e\n    fetch(url, { signal: abortSignal })\n      .then(/* … */)\n      .catch((rejection) =\u003e {\n        if (rejection.name !== 'AbortError') {\n          // Re-throw or handle non-abort rejection in another way.\n          return Promise.reject(rejection);\n        }\n      }),\n  );\n\n  const handleManualAbort = () =\u003e abortControllerRef.current.abort();\n\n  // …\n}\n```\n\n### Arbitrary computation that can be aborted\n\n```jsx\nimport React from 'react';\nimport useAbortableEffect from '@closeio/use-abortable-effect';\n\nexport default function MyAbortableComputationComponent() {\n  const abortControllerRef = useAbortableEffect(abortSignal =\u003e {\n    new Promise((resolve, reject) =\u003e {\n      // Should be a DOMException per spec.\n      const abortRejection = new DOMException(\n        'Calculation aborted by the user',\n        'AbortError',\n      );\n\n      // Handle when abort was requested before starting the computation.\n      if (abortSignal.aborted) {\n        return reject(abortRejection);\n      }\n\n      // This simulates an expensive computation.\n      const timeout = setTimeout(() =\u003e resolve(1), 5000);\n\n      // Listen for abort request.\n      abortSignal.addEventListener('abort', () =\u003e {\n        clearTimeout(timeout);\n        reject(abortRejection);\n      });\n    })\n      .then(/* … */)\n      .catch(rejection =\u003e {\n        if (rejection.name !== 'AbortError') {\n          // Re-throw or handle non-abort rejection in another way.\n          return Promise.reject(rejection);\n        }\n      }),\n  });\n\n  const handleManualAbort = () =\u003e abortControllerRef.current.abort();\n\n  // …\n}\n```\n\n### Custom cleanup function\n\n```jsx\nimport React from 'react';\nimport useAbortableEffect from '@closeio/use-abortable-effect';\n\nexport default function MyCustomCleanupComponent() {\n  const [gotAborted, setGotAborted] = useState(false);\n\n  const abortControllerRef = useAbortableEffect((abortSignal) =\u003e {\n    fetch(url, { signal: abortSignal })\n      .then(/* … */)\n      .catch((rejection) =\u003e {\n        if (rejection.name !== 'AbortError') {\n          // Re-throw or handle non-abort rejection in another way.\n          return Promise.reject(rejection);\n        }\n      });\n\n    // Just return a function like in `useEffect`, with the difference that you\n    // get the abort controller (not a ref) as a param.\n    return (controller) =\u003e {\n      controller.abort();\n      setGotAborted(true);\n    };\n  });\n\n  const handleManualAbort = () =\u003e abortControllerRef.current.abort();\n\n  // …\n}\n```\n\n## License\n\nMIT © [Close](https://github.com/closeio)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloseio%2Fuse-abortable-effect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloseio%2Fuse-abortable-effect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloseio%2Fuse-abortable-effect/lists"}