### Install and Start Example Project
Source: https://github.com/async-library/react-async/blob/next/examples/with-react-router/README.md
Standard npm commands to install dependencies and start the development server for the example project.
```bash
npm install
npm start
```
--------------------------------
### Build and Run Example Applications
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/development.md
Commands to build, test, and start the example applications located in the `examples` folder. These examples showcase various uses of React Async.
```sh
yarn build:examples
```
```sh
yarn test:examples
```
```sh
yarn start:examples
```
--------------------------------
### Initial Project Setup
Source: https://github.com/async-library/react-async/blob/next/CONTRIBUTING.md
Clone the repository, install dependencies, bootstrap the project, and run tests. All development should be done on the 'next' branch.
```sh
git clone https://github.com/async-library/react-async.git
cd react-async
yarn && yarn bootstrap && yarn test
```
--------------------------------
### Test Example Integrations
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/testing.md
Run tests for all examples to ensure integration with other libraries. Add new examples for compatibility testing.
```sh
yarn test:examples
```
--------------------------------
### Install React Async
Source: https://context7.com/async-library/react-async/llms.txt
Install the react-async library using npm or Yarn. React 16.3+ is required, and hooks require React 16.8+.
```bash
npm install --save react-async
# or
yarn add react-async
```
--------------------------------
### useFetch Hook - GET Request
Source: https://context7.com/async-library/react-async/llms.txt
Example of using the `useFetch` hook for a GET request. The request runs automatically on mount. The `Accept` header is set for JSON parsing.
```jsx
import { useFetch } from "react-async"
// GET — runs automatically on mount
const UserCard = ({ userId }) => {
const { data, error, isPending } = useFetch(
`/api/users/${userId}`,
{ headers: { Accept: "application/json" } }
)
if (isPending) return
Loading user…
if (error) return
Failed: {error.message}
return
Welcome, {data?.name}!
}
```
--------------------------------
### Clean and Bootstrap Dependencies
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/development.md
Run this command to resolve dependency issues by deleting `node_modules` from all packages and examples, followed by a clean installation. This is useful when dependencies are in a weird state.
```sh
yarn clean -y && yarn bootstrap
```
--------------------------------
### Install React Async DevTools with npm
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/devtools.md
Install the DevTools package using npm. This is the first step to enable debugging for asynchronous states.
```text
npm install --save react-async-devtools
```
--------------------------------
### Install React Async DevTools with Yarn
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/devtools.md
Install the DevTools package using Yarn. This is an alternative to npm for managing project dependencies.
```text
yarn add react-async-devtools
```
--------------------------------
### Install React Async with npm
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/installation.md
Use this command to add react-async to your project's dependencies via npm.
```bash
npm install --save react-async
```
--------------------------------
### Clone and Bootstrap React Async Project
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/setting-up.md
Clone the repository, install dependencies, bootstrap the project, and run tests. Ensure you are on the 'next' branch for development.
```sh
git clone https://github.com/async-library/react-async.git
cd react-async
yarn install
yarn bootstrap
yarn test
```
--------------------------------
### Install React Async with Yarn
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/installation.md
Use this command to add react-async to your project's dependencies via Yarn.
```bash
yarn add react-async
```
--------------------------------
### Start Storybook Development Environment
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/development.md
Use this command to spin up the Storybook development environment for the React Async DevTools. It typically opens in a browser at http://localhost:6006/.
```sh
yarn start:storybook
```
--------------------------------
### useAsync Hook Example
Source: https://context7.com/async-library/react-async/llms.txt
Demonstrates the use of the `useAsync` hook for fetching data. The `promiseFn` is automatically invoked on mount. Extra props are forwarded to the `promiseFn`.
```jsx
import { useAsync } from "react-async"
// promiseFn receives all options passed to useAsync plus an AbortController
const fetchPlayer = async ({ playerId }, { signal }) => {
const res = await fetch(`/api/players/${playerId}`, { signal })
if (!res.ok) throw new Error(res.statusText)
return res.json()
}
const PlayerProfile = ({ playerId }) => {
const { data, error, isPending, reload, cancel } = useAsync({
promiseFn: fetchPlayer,
playerId,
onResolve: data => console.log("Loaded:", data),
onReject: err => console.error("Failed:", err),
})
if (isPending) return
Loading...
if (error) return
Error: {error.message}
if (data) return (
{data.name}
)
return null
}
```
--------------------------------
### Apply v6 codemod to current directory
Source: https://github.com/async-library/react-async/blob/next/codemods/README.md
This example demonstrates applying the v6 codemod to the current working directory. Replace '.' with your project's source directory if needed.
```bash
npx jscodeshift . -t https://raw.githubusercontent.com/async-library/react-async/master/codemods/v6.js
```
--------------------------------
### isInitial
Source: https://github.com/async-library/react-async/blob/next/docs/api/state.md
A boolean indicating if no promise has started yet, or if a started promise was cancelled.
```APIDOC
## `isInitial`
> `boolean`
`true` while no promise has started yet, or one was started but cancelled.
```
--------------------------------
### promise
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
An already started Promise instance. If undefined, the state will be pending. Note that `reload` will not work with `promise`; use `promiseFn` instead.
```APIDOC
## promise
> `Promise`
A Promise instance which has already started. It will simply add the necessary resolve/reject callbacks and set `startedAt` to the time `promise` was first provided. Changing the value of `promise` will cancel any pending promise and listen to the new one. If `promise` is initially undefined, the React Async state will be `pending`.
> Note that `reload` will not do anything when using `promise`. Use `promiseFn` instead.
```
--------------------------------
### Integrate React Async DevTools
Source: https://context7.com/async-library/react-async/llms.txt
Render `` at the root of your app and use `debugLabel` in `useAsync` for meaningful display in DevTools. This setup requires importing `DevTools` and `App`.
```jsx
import DevTools from "react-async-devtools"
import App from "./App"
// Render at the root of your app; use debugLabel in useAsync
export const Root = () => (
<>
>
)
// In any component, add debugLabel so it shows up meaningfully in DevTools
const MyComponent = () => {
const { data } = useAsync({
promiseFn: loadSomething,
debugLabel: "loadSomething",
})
return data ?
{data.name}
: null
}
```
--------------------------------
### Lint Code Style
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/testing.md
Verify your code style before committing using this command. It's recommended to install Prettier and ESLint IDE plugins.
```sh
yarn lint
```
--------------------------------
### counter
Source: https://github.com/async-library/react-async/blob/next/docs/api/state.md
The number of times a promise has been started.
```APIDOC
## `counter`
> `number`
The number of times a promise was started.
```
--------------------------------
### SSR Integration with Next.js
Source: https://github.com/async-library/react-async/blob/next/docs/guide/server-side-rendering.md
Example of integrating React Async with Next.js for server-side rendering. The `getInitialProps` method fetches data server-side and passes it as `initialValue` to the Async component.
```jsx
import fetch from "isomorphic-unfetch"
const fetchPerson = async ({ id }) => {
const response = await fetch(`https://swapi.co/api/people/${id}/`)
if (!response.ok) throw new Error(response.status)
return response.json()
}
const Person = ({ id, person }) => (
Loading...{error => }{data => }
)
Person.getInitialProps = async ({ req }) => {
const id = req.params.id
const person = await fetchPerson({ id })
return { id, person }
}
```
--------------------------------
### Advanced State Control with Reducer and Dispatcher
Source: https://context7.com/async-library/react-async/llms.txt
Use `reducer` to intercept and override state updates, and `dispatcher` to intercept or augment dispatched actions. This example shows logging actions and suppressing updates based on a prop.
```jsx
import { useAsync } from "react-async"
const customReducer = (state, action, internalReducer) => {
// Log every action, then delegate to the internal reducer
console.log("[AsyncReducer] action:", action.type, action)
return internalReducer(state, action)
}
const customDispatcher = (action, internalDispatch, props) => {
// Suppress updates when a "dry run" flag is set
if (props.dryRun) return
internalDispatch(action)
}
const TrackedFetch = ({ url, dryRun }) => {
const { data, isPending } = useAsync({
promiseFn: async () => fetch(url).then(r => r.json()),
reducer: customReducer,
dispatcher: customDispatcher,
dryRun,
})
return isPending ?
Loading…
:
{JSON.stringify(data)}
}
```
--------------------------------
### run
Source: https://github.com/async-library/react-async/blob/next/docs/api/state.md
Invokes the `deferFn`, passing any arguments provided. Overloaded signatures exist for `useFetch` to allow overriding resource and request initialization parameters.
```APIDOC
## `run`
> `function(...args: any[]): void`
Runs the `deferFn`, passing any arguments provided as an array.
When used with `useFetch`, `run` has several overloaded signatures:
> `function(override: OverrideParams | (params: OverrideParams) => OverrideParams): void`
>
> `function(event: SyntheticEvent | Event): void`
>
> `function(): void`
Where `type OverrideParams = { resource?: RequestInfo } & Partial`.
This way you can run the `fetch` request with custom `resource` and `init`. If `override` is an object it will be spread
over the default `resource` and `init` for `fetch`. If it's a function it will be invoked with the params defined with
`useFetch`, and should return an `override` object. This way you can either extend or override the value of `resource`
and `init`, for example to change the URL or set custom request headers.
```
--------------------------------
### useFetch Hook - POST Request
Source: https://context7.com/async-library/react-async/llms.txt
Demonstrates using `useFetch` for a POST request. The `run` function must be called manually to initiate the request. The request body can be overridden at call time.
```jsx
import { useFetch } from "react-async"
// POST — run must be called manually; body can be overridden at call time
const CreatePost = () => {
const { isPending, error, run } = useFetch("/api/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
})
const handleSubmit = (title, body) => {
run({ body: JSON.stringify({ title, body }) })
}
return (
)
}
```
--------------------------------
### Publish Packages to npm
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/releasing.md
After building packages, navigate to each package directory and publish its 'pkg' subdirectory to npm. Ensure the 'pkg' directory is published.
```bash
yarn build:packages
cd packages/react-async
npm publish pkg
cd ../react-async-devtools
npm publish pkg
```
--------------------------------
### createInstance Function
Source: https://github.com/async-library/react-async/blob/next/docs/api/interfaces.md
Allows the creation of custom instances of the Async component with pre-configured default options.
```APIDOC
## createInstance Function
### Description
This function allows you to create a customized version of the `Async` component with default options applied globally.
### Usage
```js
const CustomAsync = createInstance(defaultOptions, displayName)
```
### Parameters
- `defaultOptions` (object) - Default configuration options to be applied to all instances created by this function. See [options.md].
- `displayName` (string) - An optional name for the created instance, useful for debugging in React DevTools.
```
--------------------------------
### Create Reusable Async Instance
Source: https://context7.com/async-library/react-async/llms.txt
Use `createInstance` to generate a pre-configured ``-like component with default options. This is useful for sharing configurations like global error handlers or authentication headers across multiple usages.
```jsx
import { createInstance } from "react-async"
const loadUser = async ({ userId }, { signal }) => {
const res = await fetch(`/api/users/${userId}`, { signal })
if (!res.ok) throw new Error(res.statusText)
return res.json()
}
// Create a reusable instance with defaults and a DevTools display name
const AsyncUser = createInstance(
{
promiseFn: loadUser,
onReject: err => console.error("[AsyncUser] request failed:", err),
},
"AsyncUser" // display name shown in React DevTools
)
// Use it like a normal Async component — any prop overrides the default
const UserBadge = ({ userId }) => (
Loading user…{user => `Hello, ${user.name}`}{err => `Error: ${err.message}`}
)
```
--------------------------------
### Simplified Async Action with useFetch
Source: https://github.com/async-library/react-async/blob/next/docs/guide/async-actions.md
Use the `useFetch` hook for simplified asynchronous actions, especially for POST requests. The `run` function can override request parameters like the body.
```jsx
import React, { useState } from "react"
import { useFetch } from "react-async"
const NewsletterForm = () => {
const { isPending, error, run } = useFetch("/newsletter", { method: "POST" })
const [email, setEmail] = useState("")
const handleSubmit = event => {
event.preventDefault()
run({ body: JSON.stringify({ email }) })
}
return (
)
}
```
--------------------------------
### createInstance Function
Source: https://github.com/async-library/react-async/blob/next/docs/api/interfaces.md
Create a custom instance of the Async component with default options and a display name using the `createInstance` function.
```javascript
const CustomAsync = createInstance(defaultOptions, displayName)
```
--------------------------------
### Implement Optimistic Updates with promiseFn and deferFn
Source: https://github.com/async-library/react-async/blob/next/docs/guide/optimistic-updates.md
Use `promiseFn` for initial data fetching and `deferFn` for actions that modify data. `setData` is used to optimistically update the UI before the async action completes. Both functions should resolve to similar data types.
```jsx
import Async from "react-async"
const getAttendance = () => fetch("/attendance").then(() => true, () => false)
const updateAttendance = ([attend]) =>
fetch("/attendance", { method: attend ? "POST" : "DELETE" }).then(() => attend, () => !attend)
const AttendanceToggle = () => (
{(asyncState) => {
const { isPending, data: isAttending, run, setData } = asyncState
return (
{
setData(!isAttending)
run(!isAttending)
}}
disabled={isPending}
/>
)
}}
)
```
--------------------------------
### startedAt
Source: https://github.com/async-library/react-async/blob/next/docs/api/state.md
Timestamp indicating when the current or last promise was initiated.
```APIDOC
## `startedAt`
> `Date`
Tracks when the current/last promise was started.
```
--------------------------------
### useFetch Hook Usage
Source: https://github.com/async-library/react-async/blob/next/docs/api/interfaces.md
Employ the `useFetch` hook for fetching resources using the native fetch API. It accepts the resource, initialization options, and configuration options.
```javascript
const state = useFetch(resource, init, options)
```
--------------------------------
### Manual Async Action with deferFn
Source: https://github.com/async-library/react-async/blob/next/docs/guide/async-actions.md
Use `deferFn` with `useAsync` to manually trigger asynchronous actions like form submissions. The `run` function is called with arguments to initiate the action.
```jsx
import React, { useState } from "react"
import { useAsync } from "react-async"
const subscribe = ([email], props, { signal }) =>
fetch("/newsletter", { method: "POST", body: JSON.stringify({ email }), signal })
const NewsletterForm = () => {
const { isPending, error, run } = useAsync({ deferFn: subscribe })
const [email, setEmail] = useState("")
const handleSubmit = event => {
event.preventDefault()
run(email)
}
return (
)
}
```
--------------------------------
### Create Pre-configured Async Instances with createInstance
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/usage.md
The createInstance factory function allows you to create reusable Async component instances with pre-configured options, such as default promiseFn or callbacks. This is useful for creating specialized components.
```jsx
import { createInstance } from "react-async"
const loadPlayer = async ({ playerId }, { signal }) => {
const res = await fetch(`/api/players/${playerId}`, { signal })
if (!res.ok) throw new Error(res.statusText)
return res.json()
}
// createInstance takes a defaultOptions object and a displayName (both optional)
const AsyncPlayer = createInstance({ promiseFn: loadPlayer }, "AsyncPlayer")
const MyComponent = () => (
{player => `Hello ${player.name}`}
)
```
--------------------------------
### Use useFetch Hook for Fetch API Integration
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/usage.md
The useFetch hook simplifies using the Fetch API with useAsync. It automatically handles promiseFn/deferFn and JSON parsing based on request method and headers. You can modify fetch init parameters by calling `run` with a callback or an object.
```jsx
import { useFetch } from "react-async"
const MyComponent = () => {
const headers = { Accept: "application/json" }
const { data, error, isPending, run } = useFetch("/api/example", { headers }, options)
// This will setup a promiseFn with a fetch request and JSON deserialization.
// you can later call `run` with an optional callback argument to
// last-minute modify the `init` parameter that is passed to `fetch`
function clickHandler() {
run(init => ({
...init,
headers: {
...init.headers,
authentication: "...",
},
}))
}
// alternatively, you can also just use an object that will be spread over `init`.
// please note that this is not deep-merged, so you might override properties present in the
// original `init` parameter
function clickHandler2() {
run({ body: JSON.stringify(formValues) })
}
}
```
--------------------------------
### Async Component Usage
Source: https://github.com/async-library/react-async/blob/next/docs/api/interfaces.md
Use the `` component with configuration options and a render prop to access state. Options can be passed individually.
```jsx
{state => ...}
```
--------------------------------
### Create Async Component with useFetch
Source: https://github.com/async-library/react-async/blob/next/docs/guide/async-components.md
Use the `useFetch` hook for straightforward data fetching in React components. It simplifies the process of loading data and handling its states.
```jsx
import React from "react"
import { useFetch } from "react-async"
const Person = ({ id }) => {
const { data, error } = useFetch(`https://swapi.co/api/people/${id}/`, {
headers: { accept: "application/json" },
})
if (error) return error.message
if (data) return `Hi, my name is ${data.name}!`
return null
}
const App = () => {
return
}
```
--------------------------------
### `suspense` Option
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Enables experimental Suspense integration, causing React Async to throw a promise while loading. This allows for fallback UI rendering via `` components.
```APIDOC
## `suspense`
> `boolean`
Enables **experimental** Suspense integration. This will make React Async throw a promise while loading, so you can use Suspense to render a fallback UI, instead of using ``. Suspense differs in 2 main ways:
- `` should be an ancestor of your Async component, instead of a descendant. It can be anywhere up in the
component hierarchy.
- You can have a single `` wrap multiple Async components, in which case it will render the fallback UI until
all promises are settled.
> Note that the way Suspense is integrated right now may change. Until Suspense for data fetching is officially released, we may make breaking changes to its integration in React Async in a minor or patch release. Among other things, we'll probably add a cache of sorts.
```
--------------------------------
### suspense
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Enables experimental Suspense integration for concurrent rendering capabilities.
```APIDOC
- [`suspense`](#suspense) Enable **experimental** Suspense integration.
```
--------------------------------
### Server-side Rendering with initialValue
Source: https://context7.com/async-library/react-async/llms.txt
Integrate with server-side rendering by providing pre-fetched data via `initialValue`. This bypasses the initial loading state on the client, as React Async uses the provided data immediately without invoking `promiseFn` on the first render. This is commonly used with frameworks like Next.js.
```jsx
import fetch from "isomorphic-unfetch"
import Async from "react-async"
const fetchPerson = async ({ id }) => {
const res = await fetch(`https://swapi.co/api/people/${id}/`)
if (!res.ok) throw new Error(res.status)
return res.json()
}
// Client component — initialValue is hydrated from server props
const Person = ({ id, person }) => (
Loading…{error =>
Error: {error.message}
}{data =>
Hello, {data.name}!
}
)
// Next.js page — fetch server-side and pass as initialValue
Person.getInitialProps = async ({ req }) => {
const id = req.params.id
const person = await fetchPerson({ id })
return { id, person }
}
```
--------------------------------
### Create Async Component with useAsync
Source: https://github.com/async-library/react-async/blob/next/docs/guide/async-components.md
Utilize the `useAsync` hook for advanced control over asynchronous operations, such as combining multiple requests. It requires a `promiseFn` that returns a Promise.
```jsx
import React from "react"
import { useAsync } from "react-async"
const fetchPerson = async ({ id }, { signal }) => {
const response = await fetch(`https://swapi.co/api/people/${id}/`, { signal })
if (!response.ok) throw new Error(response.status)
return response.json()
}
const Person = ({ id }) => {
const { data, error } = useAsync({ promiseFn: fetchPerson, id })
if (error) return error.message
if (data) return `Hi, my name is ${data.name}!`
return null
}
const App = () => {
return
}
```
--------------------------------
### json (useFetch specific)
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Enables JSON parsing of the response for `useFetch` operations.
```APIDOC
- [`json`](#json) Enable JSON parsing of the response.
```
--------------------------------
### useFetch Hook
Source: https://github.com/async-library/react-async/blob/next/docs/api/interfaces.md
A specialized hook based on useAsync, specifically designed to work with the native Fetch API.
```APIDOC
## useFetch Hook
### Description
This hook is a convenience wrapper around `useAsync` that integrates directly with the native `fetch` API.
### Usage
```js
const state = useFetch(resource, init, options)
```
### Parameters
- `resource` (string | Request) - The URL or Request object to fetch. See [fetch api].
- `init` (object) - Optional. Custom request options for the fetch call. See [fetch api].
- `options` (object) - Optional. Configuration options for React Async. See [options.md].
```
--------------------------------
### IfInitial / Async.Initial
Source: https://github.com/async-library/react-async/blob/next/docs/api/helpers.md
Renders content only while the deferred promise is still waiting to be run, or when no promise has been provided. It can persist its children until data is available, even during loading or error states.
```APIDOC
## IfInitial / Async.Initial
Renders only while the deferred promise is still waiting to be run, or you have not provided any promise.
### Props
- `children` `function(state: Object): Node | Node` Render function or React Node.
- `state` `object` Async state object (return value of `useAsync()`).
- `persist` `boolean` Show until we have data, even while loading or when an error occurred. By default it hides as soon as the promise starts loading.
### Examples
```jsx
const state = useAsync(...)
return (
This text is only rendered while `run` has not yet been invoked on `deferFn`.
)
```
```jsx
This text is only rendered while `run` has not yet been invoked on `deferFn`.
```
```jsx
{({ error, isPending, run }) => (
This text is only rendered while the promise has not fulfilled yet.
{error &&
{error.message}
}
)}
```
```
--------------------------------
### Async Component with Render Props
Source: https://context7.com/async-library/react-async/llms.txt
Use the `` component with render props to manage asynchronous operations. It accepts configuration options and exposes state to its children function. Ensure the promise function handles cancellation via the `signal`.
```jsx
import Async from "react-async"
const loadPlayer = async ({ playerId }, { signal }) => {
const res = await fetch(`/api/players/${playerId}`, { signal })
if (!res.ok) throw new Error(res.statusText)
return res.json()
}
// Using render props directly
const PlayerRaw = () => (
{({ data, error, isPending }) => {
if (isPending) return "Loading..."
if (error) return `Error: ${error.message}`
return data ?
{JSON.stringify(data, null, 2)}
: null
}}
)
```
--------------------------------
### `reducer` Option
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Allows full control over state updates by wrapping the internal reducer. It receives the current state, the dispatched action, and the internal reducer. Invoking the internal reducer is recommended.
```APIDOC
## `reducer`
> `function(state: any, action: Object, internalReducer: function(state: any, action: Object))`
State reducer to take full control over state updates by wrapping the [internal reducer](https://github.com/async-library/react-async/blob/master/packages/react-async/src/reducer.ts). It receives the current state, the dispatched action and the internal reducer. You probably want to invoke the internal reducer at some point.
> This is a power feature which loosely follows the [state reducer pattern](https://kentcdodds.com/blog/the-state-reducer-pattern). It allows you to control state changes by intercepting actions before they are handled, or by overriding or enhancing the reducer itself.
```
--------------------------------
### initialValue
Source: https://github.com/async-library/react-async/blob/next/docs/api/state.md
The initial data or error provided through the `initialValue` prop.
```APIDOC
## `initialValue`
> `any | Error`
The data or error that was originally provided through the `initialValue` prop.
```
--------------------------------
### Run All Tests in Watch Mode
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/testing.md
Use this command to test all packages in watch mode during development. Refer to Jest CLI options for more details.
```sh
yarn test:watch
```
--------------------------------
### Async Component with Helper Sub-components
Source: https://context7.com/async-library/react-async/llms.txt
Leverage helper sub-components like ``, ``, and `` for cleaner conditional rendering within the `` component. These are automatically wired via React Context.
```jsx
import Async from "react-async"
const loadPlayer = async ({ playerId }, { signal }) => {
const res = await fetch(`/api/players/${playerId}`, { signal })
if (!res.ok) throw new Error(res.statusText)
return res.json()
}
// Using helper sub-components (recommended — no if/else needed)
const PlayerClean = () => (
Loading…{error => `Something went wrong: ${error.message}`}
{(data, { finishedAt }) => (
{data.name}
Last updated: {finishedAt.toISOString()}
)}
)
```
--------------------------------
### Test React Compatibility
Source: https://github.com/async-library/react-async/blob/next/docs/contributing/testing.md
Execute all tests with various versions of React and ReactDOM to check for compatibility with older and newer versions. This is used in CI.
```sh
yarn test:compat
```
--------------------------------
### initialValue
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Provides initial data or an error for server-side rendering. Sets status to `fulfilled` or `rejected` immediately, skipping `promiseFn` invocation. `onResolve`/`onReject` are not called.
```APIDOC
## initialValue
> `any | Error`
Initial state for `data` or `error` (if instance of Error); useful for server-side rendering. When an `initialValue` is provided, the `promiseFn` will not be invoked on first render. Instead, `status` will be immediately set to `fulfilled` or `rejected` and your components will render accordingly. If you want to trigger the `promiseFn` regardless, you can call `reload()` or use the `watch` or `watchFn` option.
> Note that `onResolve` or `onReject` is not invoked in this case and no `promise` prop will be created.
```
--------------------------------
### defer (useFetch specific)
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Forces the use of `deferFn` or `promiseFn` for `useFetch` operations.
```APIDOC
`useFetch` additionally takes these options:
- [`defer`](#defer) Force the use of `deferFn` or `promiseFn`.
```
--------------------------------
### `defer` Option
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Controls whether `deferFn` or `promiseFn` is used. Defaults to automatic selection based on the request method.
```APIDOC
## `defer`
> `boolean`
Enables the use of `deferFn` if `true`, or enables the use of `promiseFn` if `false`. By default this is automatically chosen based on the request method (`deferFn` for POST / PUT / PATCH / DELETE, `promiseFn` otherwise).
```
--------------------------------
### IfPending / Async.Pending / Async.Loading
Source: https://github.com/async-library/react-async/blob/next/docs/api/helpers.md
This component renders only while the promise is pending (loading or unsettled). It can be configured to show only on the initial load.
```APIDOC
## IfPending / Async.Pending / Async.Loading
This component renders only while the promise is pending (loading / unsettled).
Alias: ``
### Props
- `children` `function(state: Object): Node | Node` Render function or React Node.
- `state` `object` Async state object (return value of `useAsync()`).
- `initial` `boolean` Show only on initial load (when `data` is `undefined`).
### Examples
```jsx
const state = useAsync(...)
return (
This text is only rendered while performing the initial load.
)
```
```jsx
This text is only rendered while performing the initial load.
```
```jsx
{({ startedAt }) => `Loading since ${startedAt.toISOString()}`}
```
```
--------------------------------
### Run jscodeshift with a codemod script
Source: https://github.com/async-library/react-async/blob/next/codemods/README.md
Use this command to apply a codemod script to your project's target directory. Ensure your files are version controlled before running.
```bash
npx jscodeshift -t
```
--------------------------------
### Conditional Rendering with Async Compound Components
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/usage.md
Utilize the static helper components of `` (e.g., ``) for conditional rendering. These components automatically access the state via Context, eliminating the need to pass the state object explicitly.
```jsx
import Async from "react-async"
const loadPlayer = async ({ playerId }, { signal }) => {
const res = await fetch(`/api/players/${playerId}`, { signal })
if (!res.ok) throw new Error(res.statusText)
return res.json()
}
const MyComponent = () => (
Loading...
{data => (
Player data:
{JSON.stringify(data, null, 2)}
)}
{error => `Something went wrong: ${error.message}`}
)
```
--------------------------------
### Render DevTools Component in App
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/devtools.md
Import and render the `` component at the root of your application. This makes the DevTools available for debugging.
```jsx
import DevTools from "react-async-devtools"
export const Root = () => (
<>
>
)
```
--------------------------------
### Conditional Rendering with useAsync Helper Components
Source: https://github.com/async-library/react-async/blob/next/docs/getting-started/usage.md
Use `IfPending`, `IfFulfilled`, and `IfRejected` with the `useAsync` hook to conditionally render UI elements based on the promise state. Pass the state object returned by `useAsync` to each helper component.
```jsx
import { useAsync, IfPending, IfFulfilled, IfRejected } from "react-async"
const loadPlayer = async ({ playerId }, { signal }) => {
// ...
}
const MyComponent = () => {
const state = useAsync({ promiseFn: loadPlayer, playerId: 1 })
return (
<>
Loading...{error => `Something went wrong: ${error.message}`}
{data => (
Player data:
{JSON.stringify(data, null, 2)}
)}
>
)
}
```
--------------------------------
### promiseFn
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
A function that returns a promise. It is automatically invoked on mount and updates. It receives component props and an AbortController. Avoid inline functions to prevent unnecessary reloads.
```APIDOC
## promiseFn
> `function(props: Object, controller: AbortController): Promise`
A function that returns a promise. It is automatically invoked in `componentDidMount` and `componentDidUpdate`. The function receives all component props (or options) and an AbortController instance as arguments.
> Be aware that updating `promiseFn` will trigger it to cancel any pending promise and load the new promise. Passing an inline (arrow) function will cause it to change and reload on every render of the parent component. You can avoid this by defining the `promiseFn` value **outside** of the render method. If you need to pass variables to the `promiseFn`, pass them as additional props to ``, as `promiseFn` will be invoked with these props. Alternatively you can use `useCallback` or [memoize-one](https://github.com/alexreardon/memoize-one) to avoid unnecessary updates.
```
--------------------------------
### Enable Suspense Integration in React Async
Source: https://context7.com/async-library/react-async/llms.txt
Pass `suspense: true` to `useAsync` to enable experimental Suspense support. This allows parent `` boundaries to render fallbacks during loading.
```jsx
import React, { Suspense } from "react"
import { useAsync } from "react-async"
const loadData = async () => {
const res = await fetch("/api/data")
return res.json()
}
const DataDisplay = () => {
// With suspense:true, this component suspends while loading — no isPending check needed
const { data } = useAsync({ promiseFn: loadData, suspense: true })
return
{JSON.stringify(data, null, 2)}
}
const App = () => (
Loading…}>
)
```
--------------------------------
### Cleaner JSX with Async Component and State Helpers
Source: https://github.com/async-library/react-async/blob/next/docs/guide/separating-view-logic.md
Utilize the `` component and its state helpers for a more declarative JSX structure, eliminating the need for explicit if/else statements and return keywords when handling async states.
```jsx
import React from "react"
import Async from "react-async"
const fetchPerson = async ({ id }, { signal }) => {
const response = await fetch(`https://swapi.co/api/people/${id}/`, { signal })
if (!response.ok) throw new Error(response.statusText)
return response.json()
}
const App = () => {
return (
Loading...{error => }{data => }
)
}
```
--------------------------------
### finishedAt
Source: https://github.com/async-library/react-async/blob/next/docs/api/state.md
Timestamp indicating when the last promise was fulfilled or rejected.
```APIDOC
## `finishedAt`
> `Date`
Tracks when the last promise was resolved or rejected.
```
--------------------------------
### VS Code ESLint Configuration
Source: https://github.com/async-library/react-async/blob/next/CONTRIBUTING.md
Configure VS Code settings for ESLint to enable auto-fixing, specify the package manager, and define validation languages and options.
```json
{
"eslint.autoFixOnSave": true,
"eslint.packageManager": "yarn",
"eslint.options": {
"cache": true,
"cacheLocation": ".cache/eslint",
"extensions": [".js", ".jsx", ".mjs", ".json", ".ts", ".tsx"]
},
"eslint.validate": [
"javascript",
"javascriptreact",
{"language": "typescript", "autoFix": true },
{"language": "typescriptreact", "autoFix": true }
],
"eslint.alwaysShowStatus": true
}
```
--------------------------------
### deferFn
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
A function that returns a promise, invoked manually via `run(...args)`. Useful for actions like form submissions. Arguments passed to `run` are forwarded. Ensure its fulfilled value matches `promiseFn` if both are used.
```APIDOC
## deferFn
> `function(args: any[], props: Object, controller: AbortController): Promise`
A function that returns a promise. This is invoked only by manually calling `run(...args)`. Any arguments to `run` are passed-through as an array via `args`, so you can pass data through either `args` or `props`, as needed. The `deferFn` is commonly used to send data to the server following a user action, such as submitting a form. You can use this in conjunction with `promiseFn` to fill the form with existing data, then updating it on submit with `deferFn`.
> Be aware that when using both `promiseFn` and `deferFn`, the shape of their fulfilled value should match, because they both update the same `data`.
```
--------------------------------
### Declarative Routing with Data Fetching
Source: https://github.com/async-library/react-async/blob/next/examples/with-react-router/README.md
Configure routes with associated data fetching URLs and components using ApiRouter. This allows for declarative data loading tied to specific paths.
```jsx
...
```
--------------------------------
### Logic-Only Async Component with Render Props
Source: https://github.com/async-library/react-async/blob/next/docs/guide/separating-view-logic.md
Use this pattern to create a logic-only async component that passes down async state via render props. This separates data fetching logic from UI rendering.
```jsx
import React from "react"
import { useAsync } from "react-async"
const fetchPerson = async ({ id }, { signal }) => {
const response = await fetch(`https://swapi.co/api/people/${id}/`, { signal })
if (!response.ok) throw new Error(response.statusText)
return response.json()
}
const Person = ({ id }) => {
const state = useAsync({ promiseFn: fetchPerson, id })
return children(state)
}
const App = () => {
return (
{({ isPending, data, error }) => {
if (isPending) return "Loading..."
if (error) return
if (data) return
return null
}}
)
}
```
--------------------------------
### Automatic Re-runs with watch and watchFn
Source: https://context7.com/async-library/react-async/llms.txt
Use `watch` to automatically re-run a `promiseFn` when a specific prop changes (based on reference equality). For more complex dependency logic, `watchFn` allows custom comparison functions to determine when a re-run is necessary.
```jsx
import { useAsync } from "react-async"
const fetchSearch = async ({ query }, { signal }) => {
const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal })
if (!res.ok) throw new Error(res.statusText)
return res.json()
}
const SearchResults = ({ query }) => {
// Re-runs automatically whenever `query` prop changes
const { data, isPending } = useAsync({
promiseFn: fetchSearch,
watch: query, // re-runs when `query` reference changes
query,
})
return (
{isPending &&
Searching…
}
{data && data.map(r =>
{r.title}
)}
)
}
// Using watchFn for a custom comparison
const SearchResultsCustom = ({ filters }) => {
const { data } = useAsync({
promiseFn: fetchSearch,
watchFn: (props, prevProps) => props.filters.query !== prevProps.filters.query,
filters,
query: filters.query,
})
return data ?
{data.map(r =>
{r.title}
)}
: null
}
```
--------------------------------
### promise
Source: https://github.com/async-library/react-async/blob/next/docs/api/state.md
A reference to the internal wrapper promise, which can be chained on. Note: If chaining, a rejection handler must be provided to prevent uncaught exceptions.
```APIDOC
## `promise`
> `Promise`
A reference to the internal wrapper promise created when starting a new promise (either automatically or by invoking
`run` / `reload`). It fulfills or rejects along with the provided `promise` / `promiseFn` / `deferFn`. Useful as a
chainable alternative to the `onResolve` / `onReject` callbacks.
Warning! If you chain on `promise`, you MUST provide a rejection handler (e.g. `.catch(...)`). Otherwise React will
throw an exception and crash if the promise rejects.
```
--------------------------------
### watch
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Watches a property for changes using reference equality (`!==`). If the value changes, `promiseFn` is re-run. For complex checks, use `watchFn`.
```APIDOC
## watch
> `any`
Watches this property through `componentDidUpdate` and re-runs the `promiseFn` when the value changes, using a simple reference check (`oldValue !== newValue`). If you need a more complex update check, use `watchFn` instead.
```
--------------------------------
### useAsync Hook Usage
Source: https://github.com/async-library/react-async/blob/next/docs/api/interfaces.md
Utilize the `useAsync` hook by passing options as an inline object literal and destructuring the state object for needed properties.
```javascript
const state = useAsync(options)
```
--------------------------------
### `dispatcher` Option
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Provides full control over action dispatching by wrapping the internal dispatcher. It receives the original action, the internal dispatcher, and all component props (or options). Invoking the internal dispatcher is recommended.
```APIDOC
## `dispatcher`
> `function(action: Object, internalDispatch: function(action: Object), props: Object)`
Action dispatcher to take full control over action dispatching by wrapping the internal dispatcher. It receives the original action, the internal dispatcher and all component props (or options). You probably want to invoke the internal dispatcher at some point.
> This is a power feature similar to the [state reducer pattern](https://kentcdodds.com/blog/the-state-reducer-pattern). It allows you to control state changes by intercepting actions before they are dispatched, to dispatch additional actions, possibly later in time.
```
--------------------------------
### onReject
Source: https://github.com/async-library/react-async/blob/next/docs/api/options.md
Callback function invoked when a promise rejects, receiving the rejection reason (error) as an argument.
```APIDOC
## onReject
> `function(reason: Error): void`
Callback function invoked when a promise rejects, receives rejection reason (error) as argument.
```