> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nexudus.com/llms.txt
> Use this file to discover all available pages before exploring further.

# useData

> React Query-based data fetching hook with shape, pagination, method, and mock support.

# useData

`useData` is a lightweight wrapper around React Query that standardizes HTTP calls, adds first-class support for server-side shaping, pagination, and an optional `mockData` override for editor scenarios.

Source: `src/api/fetchData.ts`

## Signature

```ts theme={null}
function useData<T>(
  apiClient: HttpClient,
  url: string | null,
  requestConfig?: {
    method?: 'get' | 'post' | 'put' | 'delete'
    data?: any
    queryConfig?: Partial<QueryObserverOptions<T>>
    shape?: string[]
    page?: number
    size?: number
    mockData?: T
  },
): {
  resource: T | undefined
  hasError: boolean
  isLoading: boolean
  query?: Omit<UseQueryResult<T>, 'data' | 'isError' | 'isLoading'>
}
```

## Behavior

* Adds `_shape=...` to the URL when `shape` is provided (comma-separated fields)
* Adds `page` and `size` if provided
* Uses React Query to fetch with a stable key that includes:
  * `finalUrl`, `method`, `data`, `apiClient.defaults.baseURL`, and `apiClient.defaults.headers`
* Disables retry for HTTP 401 errors; otherwise retries up to 3 times
* If `mockData` is provided, short-circuits and returns it immediately with `isLoading: false`

Note on caching: headers are part of the query key; token/header changes will revalidate. If you need header-agnostic caching, use `useSuspenseFetch` with `includeHeaders: false`.

## Examples

### GET with shaping and pagination

```tsx theme={null}
import { useData } from '@/api/fetchData'
import { useLocationByRouteContext } from '@/states/useLocationByRouteContext'

export function UseDataExample() {
  const { httpClient } = useLocationByRouteContext()
  const { resource, isLoading, hasError } = useData<{ Records: Array<{ Id: number; Name: string }> }>(httpClient, '/api/public/teams/my', {
    shape: ['Records.Id', 'Records.Name'],
    page: 1,
    size: 20,
    queryConfig: { staleTime: 60_000 },
  })

  if (isLoading) return <div>Loading…</div>
  if (hasError) return <div>Failed to load</div>
  return <pre>{JSON.stringify(resource, null, 2)}</pre>
}
```

### POST with payload

```tsx theme={null}
const { resource } = useData<{ Success: boolean }>(httpClient, '/api/public/helpdesk/messages', {
  method: 'post',
  data: { subject: 'Printer', message: 'Paper jam on Floor 2' },
})
```

### Editor/mock data

```tsx theme={null}
const { resource } = useData(httpClient, '/api/public/faqs', {
  mockData: { FaqArticles: [{ Question: 'Q?', Answer: 'A!' }], OpenAiEnabled: false },
})
```

## Return values

* `resource` – The typed response or `undefined` while loading
* `isLoading` – React Query loading flag
* `hasError` – React Query error flag (boolean)
* `query` – The rest of the React Query result (methods, status) minus the basic fields

## Edge cases

* `url` is `null`/falsy → hook is disabled (`enabled: false`) and no request is made
* 401 Unauthorized → no retries (fast-fail to let auth state respond)

## See also

* [useTypedData](/developers/data/use-typed-data) – Strongly-typed wrapper around `useData`
* [createShape](/developers/data/create-shape) – Type-safe shape builder for `_shape` query
* [LocationContext](/developers/state/location-context) – Ensure you call with the correct `httpClient`
