{"id":15314260,"url":"https://github.com/barelyhuman/react-async","last_synced_at":"2026-02-04T08:08:37.372Z","repository":{"id":101913386,"uuid":"428136046","full_name":"barelyhuman/react-async","owner":"barelyhuman","description":"async utilities for react (hooks, views, and more)","archived":false,"fork":false,"pushed_at":"2021-11-25T12:23:32.000Z","size":33,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"dev","last_synced_at":"2025-06-16T16:20:11.424Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/barelyhuman.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,"zenodo":null},"funding":{"liberapay":"reaper","ko_fi":"barelyreaper","github":"barelyhuman","custom":"https://barelyreaper.gumroad.com/coffee"}},"created_at":"2021-11-15T05:38:27.000Z","updated_at":"2025-05-03T08:24:35.000Z","dependencies_parsed_at":"2023-03-13T15:25:04.052Z","dependency_job_id":null,"html_url":"https://github.com/barelyhuman/react-async","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/barelyhuman/react-async","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barelyhuman%2Freact-async","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barelyhuman%2Freact-async/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barelyhuman%2Freact-async/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barelyhuman%2Freact-async/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/barelyhuman","download_url":"https://codeload.github.com/barelyhuman/react-async/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barelyhuman%2Freact-async/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265483894,"owners_count":23774291,"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-10-01T08:44:53.976Z","updated_at":"2026-02-04T08:08:32.352Z","avatar_url":"https://github.com/barelyhuman.png","language":"JavaScript","funding_links":["https://liberapay.com/reaper","https://ko-fi.com/barelyreaper","https://github.com/sponsors/barelyhuman","https://barelyreaper.gumroad.com/coffee"],"categories":[],"sub_categories":[],"readme":"# react-async\n\n\u003e async utilities for react (hooks, views, and more)\n\n## Why?\n\n[You can read that here](https://reaper.im/posts/working-with-async-code-in-react.html)\n\n## Installation\n\n```sh\nnpm i @barelyhuman/react-async\n# or\nyarn add @barelyhuman/react-async\n```\n\n## Usage\n\nThe lib comes with 3 utilites to help you work with async code.\n\n- [`AsyncView`](#asyncview)\n- [`useAsyncEffect`](#useasynceffect)\n- [`useAsync`](#useasync)\n\n### AsyncView\n\n`AsyncView` is a simple View that renders the children with a certain set of parameters to allow using asynchronous data.\n\nThis is best for cases where you are writing a simple component that's isolated and at max uses one datasource render.\n\nBy _one datasource_ I mean that you render the `AsyncView` once in the component without having to nest it inside other `AsyncView`'s in the same component tree.\n\nExample:\n\n```jsx\n\u003c\u003e\n  \u003cAsyncView data={_fetchAdminProfile} options={{ params: id, pause: !id }}\u003e\n    {({ data, loading, error }) =\u003e {\n      if (loading) {\n        return (\n          \u003cView\u003e\n            \u003cText\u003eLoading...\u003c/Text\u003e\n          \u003c/View\u003e\n        );\n      }\n      if (error) {\n        return (\n          \u003cView\u003e\n            \u003cText error\u003e{error.message}\u003c/Text\u003e\n          \u003c/View\u003e\n        );\n      }\n      return (\n        \u003c\u003e\n          \u003cNavigationLayout title={data.name} left={\u003cAppBar.BackButton /\u003e}\u003e\n            \u003cProfileCard data={data} onUpdate={onRefetchData} /\u003e\n            \u003cAdminProfileTabs data={data} onUpdate={onRefetchData} /\u003e\n          \u003c/NavigationLayout\u003e\n        \u003c/\u003e\n      );\n    }}\n  \u003c/AsyncView\u003e\n\u003c/\u003e\n```\n\nAs mentioned before, best practice for this component is pretty limited to isolated data points. Here, the `_fetchAdminProfile` is a helper/sdk function from outside the component file and it's work is to just return the data or `throw` an error based on which the children params are provided\n\n### useAsyncEffect\n\nThis is a simple wrapper around `useEffect` that allows you to run `async` functions with the needed dependencies, the usecases for these match the above but aren't limited to a single datasource since you can manipulate state from here for as many as required.\n\nIt is still recommended to offload this effect into a custom data hook for your component and manage state there to keep your component code easy to manage.\n\nExample:\n\n```jsx\n// sdk.js\n\n// naive example of handling a request, you might need a better fetch handler like\n// ky from sindre or fetch-retry from vercel\nfunction fetchUser() {\n  let userData;\n  return fetch(URLS.USER)\n    .then((r) =\u003e {\n      if (!r.ok) {\n        return Promise.reject(r);\n      }\n      return r.json();\n    })\n    .then((_userData) =\u003e {\n      userData = _userData;\n      return fetch(URLS.USER_ADDRESS);\n    })\n    .then((r) =\u003e {\n      if (!r.ok) {\n        return Promise.reject(r);\n      }\n      return r.json();\n    })\n    .then(addressDetails=\u003e{\n        userData.address = {\n            ....addressDetails\n        }\n        return userData;\n    });\n}\n\nexport const SDK = {\n  fetchUser,\n};\n---\n// component.js\nuseAsyncEffect(async () =\u003e {\n  const response = await SDK.fetchUser(id);\n  setUserDetails(response.data);\n}, [id]);\n```\n\n### useAsync\n\nA custom hook for data fetching, that accepts a fetching promise and returns `{error, loading, data}` like any other fetching library in the community.\n\nconsidering the same `fetchUser` from above\n\nExample:\n\n```jsx\nfunction Component({ id, ...props }) {\n  const { data, error, loading, refetch } = useAsync(SDK.fetchUser, {\n    // the parameter to pass to the function\n    params: id,\n    // wait for this condition to be `false`\n    pause: !id,\n  });\n\n  const onRefetch = () =\u003e {\n    refetch(id); //=\u003e send new params\n    // refetch(); //=\u003e use the one's from the original options value\n  };\n\n  if (loading) {\n    return \u003cLoader /\u003e;\n  }\n\n  if (error) {\n    // show alert / raise toast etc\n    return \u003c\u003e\u003c/\u003e;\n  }\n\n  return \u003c\u003eHello, {data.name}\u003c/\u003e;\n}\n```\n\n### Similar\n\n- [vercel/swr](https://github.com/vercel/swr) - includes caching and revalidation\n- [async-library/react-async](https://github.com/async-library/react-async) - has a lot more features and jazz\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarelyhuman%2Freact-async","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarelyhuman%2Freact-async","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarelyhuman%2Freact-async/lists"}