# React hooks
Source: https://docs.aden.space/docs/developers/sdk/react

Client-side helpers for React and React Native apps.
The SDK ships a minimal React entrypoint at `@adenspace/sdk/react` with
hooks for common client-side concerns.

## `useApiReachable` [#useapireachable]

Poll the backend and return whether it's reachable. Useful for showing an
"offline" banner distinct from the device's connectivity state. The device
can have WiFi but your self-hosted Aden can still be down.

```tsx title="components/api-status.tsx"
'use client'

import { useApiReachable } from '@adenspace/sdk/react'
import { aden } from '@/lib/aden'

export function ApiStatus() {
    const reachable = useApiReachable(aden)

    if (reachable === null) return <span>Checking…</span>
    return reachable ? <span>Online</span> : <span>Offline</span>
}
```

### Signature [#signature]

```ts
useApiReachable(client: AdenClient, intervalMs?: number): boolean | null
```

* `client`: an `AdenClient` created with `createAdenClient`.
* `intervalMs`: poll interval. Defaults to `15_000` (15 seconds).
* Returns `null` while the first check is pending, then `true` / `false`.

<Callout>
  The hook calls `client.ping()` under the hood, which issues a `HEAD /health`
  with a 5-second timeout. It won't count against any rate limit bucket on
  your team plan.
</Callout>

## Using the SDK with React Query or SWR [#using-the-sdk-with-react-query-or-swr]

The SDK has no opinion about cache layers. Wrap calls as you would any fetch:

```tsx
import { useQuery } from '@tanstack/react-query'
import { aden } from '@/lib/aden'

export function useTracks(teamId: number) {
    return useQuery({
        queryKey: ['tracks', teamId],
        queryFn: async () => {
            const { data, error } = await aden.api.v1.tracks.get({
                query: { teamId },
            })
            if (error) throw error
            return data
        },
    })
}
```

## Server Components [#server-components]

`createAdenClient` works in Next.js Server Components, just create one per
request so you can pass through the caller's token:

```ts title="app/[locale]/my-tracks/page.tsx"
import { createClient } from '@/lib/supabase/server'
import { createAdenClient } from '@adenspace/sdk'

export default async function Page() {
    const supabase = await createClient()
    const aden = createAdenClient({
        getToken: async () => {
            const { data } = await supabase.auth.getSession()
            return data.session?.access_token ?? null
        },
    })

    const { data: tracks } = await aden.api.v1.tracks.get()
    return <TrackList tracks={tracks ?? []} />
}
```