{"id":23186070,"url":"https://github.com/termosa/use-request","last_synced_at":"2025-09-03T13:06:58.322Z","repository":{"id":57388317,"uuid":"450384784","full_name":"termosa/use-request","owner":"termosa","description":"Make it easy to use async functions with state and memoization","archived":false,"fork":false,"pushed_at":"2024-06-09T12:59:26.000Z","size":3413,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-13T00:32:46.250Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/termosa.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-21T06:51:02.000Z","updated_at":"2024-12-12T14:45:41.000Z","dependencies_parsed_at":"2024-01-09T03:20:28.723Z","dependency_job_id":"97618a0d-b179-49b1-bec8-0067a132e288","html_url":"https://github.com/termosa/use-request","commit_stats":{"total_commits":31,"total_committers":1,"mean_commits":31.0,"dds":0.0,"last_synced_commit":"7faeb9ed876d0ef8db792d4af087df8035291a76"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/termosa%2Fuse-request","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/termosa%2Fuse-request/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/termosa%2Fuse-request/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/termosa%2Fuse-request/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/termosa","download_url":"https://codeload.github.com/termosa/use-request/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230252844,"owners_count":18197284,"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-12-18T10:14:23.603Z","updated_at":"2024-12-18T10:14:24.127Z","avatar_url":"https://github.com/termosa.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `useRequest(cb, [...args])`\n\n\u003e Finally, easy way to use async functions in React\n\n[![NPM](https://img.shields.io/npm/v/use-request.svg)](https://www.npmjs.com/package/use-request)\n\nCall, observe, and persist the result of your async functions with the ease!\n\nSee how it works:\n\n```tsx\nconst RandomNumberGenerator = () =\u003e {\n  const request = useRequest(() =\u003e api('/random-number'))\n\n  return (\n    \u003cdiv\u003e\n      {request.value \u0026\u0026 \u003cp\u003eHere is your random number: {request.value}\u003c/p\u003e}\n      \u003cinput type=\"button\" value=\"Generate new number\" disabled={request.pending} onClick={request.execute} /\u003e\n      {request.error \u0026\u0026 \u003cp\u003eRequest failed due to: {request.error}\u003c/p\u003e}\n    \u003c/div\u003e\n  )\n}\n```\n\nNow, step-by-step:\n\n## Install\n\n```bash\nnpm install --save use-request\n```\n\n## Usage\n\n```tsx\nimport useRequest, { UseRequestStatus } from 'use-request'\n\nconst Example = () =\u003e {\n  const request = useRequest(\n    callback, // Async function (can be sync if needed)\n    [] // Optional arguments list. The callback will be called immediately if this is set\n  )\n\n  // Results\n\n  request.value // Last result of the callback\n  request.error // Last error thrown from the callback\n\n  // Methods\n\n  request.execute(...callbackArgs) // Proxy to trigger the callback()\n  request.reset() // Drop the state and cancel ongoing requests\n\n  // Lifecycle\n\n  request.idle // True, when request is not initialized or was reset, use for initial screen\n  request.pending // True, when the request is ongoing, use to show spinners, disabled forms, etc.\n  request.completed // True, when the request is successfully resolved\n  request.failed // True, when the request is rejected\n\n  request.status // Value of UseRequestStatus enum, helpful for tracking request status\n\n  // ...\n}\n```\n\n### The simplest usage sample\n\n```tsx\nfunction SaveButton() {\n  const request = useRequest(() =\u003e api('/save'))\n\n  return \u003cbutton onClick={request.execute}\u003esave\u003c/button\u003e\n}\n```\n\n### Make it run instantly\n\n```tsx\nfunction useUserData() {\n  const request = useRequest(() =\u003e api('/user'), [])\n\n  return request.value\n}\n```\n\n### Configure it\n\n```tsx\nfunction useUserData(userId) {\n  const request = useRequest((id) =\u003e api(`/user/${id}`), [userId])\n\n  return request.value\n}\n```\n\n### Use arguments with `execute()`\n\n```tsx\nconst RemoveButton = (id) =\u003e {\n  const request = useRequest((itemId) =\u003e api.delete(`/items/${itemId}`))\n\n  return \u003cbutton onClick={() =\u003e request.execute(id)}\u003eremove\u003c/button\u003e\n}\n```\n\n### Observe the state\n\n```tsx\nconst Button = ({ label, callback }) =\u003e {\n  const request = useRequest(callback)\n\n  return (\n    \u003cbutton onClick={request.execute} disabled={request.pending}\u003e\n      {label}\n    \u003c/button\u003e\n  )\n}\n```\n\n## More Examples\n\n### Using it for a single async function\n\n[Source code](https://github.com/termosa/use-request/blob/master/example/src/SingleFunctionExample.js)\n\n```tsx\nconst generateNumber = (max) =\u003e\n  new Promise((resolve, reject) =\u003e {\n    if (max \u003e 0) setTimeout(resolve, 2e3, Math.round(Math.random() * max))\n    else setTimeout(reject, 2e3, 'Max value must be greater than zero')\n  })\n\nconst defaultMax = 100\n\nconst SingleFunctionExample = () =\u003e {\n  const [max, setMax] = React.useState('')\n\n  const { value, error, pending } = useRequest(\n    generateNumber, // Async function that returns promise\n    [max ? +max : defaultMax] // Initial arguments\n  )\n\n  return (\n    \u003cdiv\u003e\n      \u003cdiv\u003e\n        \u003cinput type=\"number\" value={max} placeholder={defaultMax.toString()} onChange={(e) =\u003e setMax(e.target.value)} /\u003e\n        {pending ? \u003cspan\u003e processing\u003c/span\u003e : null}\n      \u003c/div\u003e\n      {value !== undefined ? \u003cdiv\u003eLast result: {value}\u003c/div\u003e : null}\n      {error ? \u003cdiv\u003eError: {error}\u003c/div\u003e : null}\n    \u003c/div\u003e\n  )\n}\n```\n\n### Create a model hook with auto-reloading\n\n[Source code](https://github.com/termosa/use-request/blob/master/example/src/MultipleFunctionsExample.js)\n\n```tsx\nconst useResources = () =\u003e {\n  const { execute: reload, value: resources, status } = useRequest(api.get, [])\n  const { execute: create } = useRequest((resource) =\u003e api.post(resource).then(reload))\n  const { execute: remove } = useRequest((id) =\u003e api.delete(id).then(reload))\n\n  return { resources, status, create, remove }\n}\n\nconst MultipleFunctionsExample = () =\u003e {\n  /** @type {React.MutableRefObject\u003cnull | HTMLInputElement\u003e} */\n  const resourceLabelRef = useRef(null)\n  const { resources, status, create, remove } = useResources()\n\n  const onSubmit = (e) =\u003e {\n    e.preventDefault()\n    if (!resourceLabelRef.current) return\n    create({ label: resourceLabelRef.current.value })\n    resourceLabelRef.current.value = ''\n  }\n\n  return (\n    \u003cdiv\u003e\n      \u003cform onSubmit={onSubmit}\u003e\n        \u003cinput type=\"text\" ref={resourceLabelRef} required /\u003e\n        \u003cinput type=\"submit\" value=\"Add\" /\u003e\n      \u003c/form\u003e\n\n      {!resources \u0026\u0026 status === UseRequestStatus.Pending ? \u003cp\u003eLoading...\u003c/p\u003e : null}\n\n      {resources ? (\n        \u003col\u003e\n          {resources.map((res) =\u003e (\n            \u003cli key={res.id}\u003e\n              {res.label} \u003cinput type=\"button\" onClick={() =\u003e remove(res.id)} value=\"remove\" /\u003e\n            \u003c/li\u003e\n          ))}\n        \u003c/ol\u003e\n      ) : null}\n    \u003c/div\u003e\n  )\n}\n```\n\n## License\n\nMIT © [termosa](https://me.st)\n\n---\n\nThis hook is created using [create-react-hook](https://github.com/hermanya/create-react-hook).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftermosa%2Fuse-request","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftermosa%2Fuse-request","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftermosa%2Fuse-request/lists"}